generator_dvi.cpp 17.7 KB
Newer Older
Pino Toscano's avatar
Pino Toscano committed
1
/***************************************************************************
2
 *   Copyright (C) 2006-2009 by Luigi Toscano <luigi.toscano@tiscali.it>   *
Pino Toscano's avatar
Pino Toscano committed
3
4
5
6
7
8
9
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/

10
11
12
13
14
15
16
#include <core/action.h>
#include <core/document.h>
#include <core/fileprinter.h>
#include <core/page.h>
#include <core/sourcereference.h>
#include <core/textpage.h>
#include <core/utils.h>
17

Pino Toscano's avatar
Pino Toscano committed
18
19
20
21
22
#include "generator_dvi.h"
#include "dviFile.h"
#include "dviPageInfo.h"
#include "dviRenderer.h"
#include "pageSize.h"
23
#include "dviexport.h"
24
#include "TeXFont.h"
Pino Toscano's avatar
Pino Toscano committed
25
26
27
28

#include <qapplication.h>
#include <qstring.h>
#include <qurl.h>
29
#include <qvector.h>
30
#include <qstack.h>
31
#include <qmutex.h>
Pino Toscano's avatar
Pino Toscano committed
32

33
#include <kaboutdata.h>
Pino Toscano's avatar
Pino Toscano committed
34
35
#include <kdebug.h>
#include <klocale.h>
36
#include <ktemporaryfile.h>
Pino Toscano's avatar
Pino Toscano committed
37

38
#ifdef DVI_OPEN_BUSYLOOP
39
40
41
42
43
44
#ifdef Q_OS_UNIX
#include <ctime>
#endif
#ifdef Q_OS_WIN
#include <windows.h> // for Sleep
#endif
45
#endif
46

47
48
static const int DviDebug = 4713;

49
static KAboutData createAboutData()
Pino Toscano's avatar
Pino Toscano committed
50
{
51
    KAboutData aboutData(
52
53
         "okular_dvi",
         "okular_dvi",
54
         ki18n( "DVI Backend" ),
55
         "0.3.1",
56
         ki18n( "A DVI file renderer" ),
57
         KAboutData::License_GPL,
58
         ki18n( "© 2006 Luigi Toscano" )
59
    );
60
61
62
63
64
65
    return aboutData;
}

OKULAR_EXPORT_PLUGIN( DviGenerator, createAboutData() )

DviGenerator::DviGenerator( QObject *parent, const QVariantList &args ) : Okular::Generator( parent, args ),
66
  m_fontExtracted( false ), m_docInfo( 0 ), m_docSynopsis( 0 ), m_dviRenderer( 0 )
67
{
68
    setFeature( Threaded );
69
    setFeature( TextExtraction );
70
    setFeature( FontInfo );
71
    setFeature( PrintPostscript );
72
73
    if ( Okular::FilePrinter::ps2pdfAvailable() )
        setFeature( PrintToFile );
Pino Toscano's avatar
Pino Toscano committed
74
75
}

76
bool DviGenerator::loadDocument( const QString & fileName, QVector< Okular::Page * > &pagesVector )
Pino Toscano's avatar
Pino Toscano committed
77
{
78
    //kDebug(DviDebug) << "file:" << fileName;
Pino Toscano's avatar
Pino Toscano committed
79
80
    KUrl base( fileName );

81
82
    (void)userMutex();

83
    m_dviRenderer = new dviRenderer(documentMetaData("TextHinting", QVariant()).toBool());
84
#ifdef DVI_OPEN_BUSYLOOP
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
    static const ushort s_waitTime = 800; // milliseconds
    static const int s_maxIterations = 10;
    int iter = 0;
    for ( ; !m_dviRenderer->isValidFile( fileName ) && iter < s_maxIterations; ++iter )
    {
        kDebug(DviDebug).nospace() << "file not valid after iteration #" << iter << "/" << s_maxIterations << ", waiting for " << s_waitTime;
#ifdef Q_OS_WIN
        Sleep( uint( s_waitTime ) );
#else
        struct timespec ts = { 0, s_waitTime * 1000 * 1000 };
        nanosleep( &ts, NULL );
#endif
    }
    if ( iter >= s_maxIterations && !m_dviRenderer->isValidFile( fileName ) )
    {
        kDebug(DviDebug) << "file still not valid after" << s_maxIterations;
        delete m_dviRenderer;
        m_dviRenderer = 0;
        return false;
    }
105
106
107
108
109
110
111
112
#else
    if ( !m_dviRenderer->isValidFile( fileName ) )
    {
        delete m_dviRenderer;
        m_dviRenderer = 0;
        return false;
    }
#endif
Pino Toscano's avatar
Pino Toscano committed
113
    if ( ! m_dviRenderer->setFile( fileName, base ) )
114
115
116
    {
        delete m_dviRenderer;
        m_dviRenderer = 0;
Pino Toscano's avatar
Pino Toscano committed
117
        return false;
118
    }
Pino Toscano's avatar
Pino Toscano committed
119

120
121
    m_dviRenderer->setParentWidget( document()->widget() );

122
    kDebug(DviDebug) << "# of pages:" << m_dviRenderer->dviFile->total_pages;
Pino Toscano's avatar
Pino Toscano committed
123

124
    m_resolution = Okular::Utils::dpiY();
125
    loadPages( pagesVector );
Pino Toscano's avatar
Pino Toscano committed
126
127
128
129

    return true;
}

130
bool DviGenerator::doCloseDocument()
131
132
133
134
135
136
137
138
{
    delete m_docInfo;
    m_docInfo = 0;
    delete m_docSynopsis;
    m_docSynopsis = 0;
    delete m_dviRenderer;
    m_dviRenderer = 0;

139
    m_linkGenerated.clear();
140
    m_fontExtracted = false;
141
142
143
144

    return true;
}

Pino Toscano's avatar
Pino Toscano committed
145
void DviGenerator::fillViewportFromAnchor( Okular::DocumentViewport &vp,
146
                                           const Anchor &anch, const Okular::Page *page ) const
Pino Toscano's avatar
Pino Toscano committed
147
148
149
150
{
    fillViewportFromAnchor( vp, anch, page->width(), page->height() );
}

151
void DviGenerator::fillViewportFromAnchor( Okular::DocumentViewport &vp,
152
                                           const Anchor &anch, int pW, int pH ) const
153
154
155
156
157
158
{
    vp.pageNumber = anch.page - 1;


    SimplePageSize ps = m_dviRenderer->sizeOfPage( vp.pageNumber );
    double resolution = 0;
159
160
    if (ps.isValid()) resolution = (double)(pW)/ps.width().getLength_in_inch();
    else resolution = m_resolution;
161
162
163

    double py = (double)anch.distance_from_top.getLength_in_inch()*resolution + 0.5; 
 
164
165
    vp.rePos.normalizedX = 0.5;
    vp.rePos.normalizedY = py/(double)pH;
166
    vp.rePos.enabled = true;
167
    vp.rePos.pos = Okular::DocumentViewport::Center;
168
}
Pino Toscano's avatar
Pino Toscano committed
169

170
QLinkedList<Okular::ObjectRect*> DviGenerator::generateDviLinks( const dviPageInfo *pageInfo )
Pino Toscano's avatar
Pino Toscano committed
171
{
172
    QLinkedList<Okular::ObjectRect*> dviLinks;
Pino Toscano's avatar
Pino Toscano committed
173

174
175
    int pageWidth = pageInfo->width, pageHeight = pageInfo->height;
    
Albert Astals Cid's avatar
Albert Astals Cid committed
176
    foreach( const Hyperlink &dviLink, pageInfo->hyperLinkList )
Pino Toscano's avatar
Pino Toscano committed
177
    {
178
        QRect boxArea = dviLink.box;
Pino Toscano's avatar
Pino Toscano committed
179
180
181
182
        double nl = (double)boxArea.left() / pageWidth,
               nt = (double)boxArea.top() / pageHeight,
               nr = (double)boxArea.right() / pageWidth,
               nb = (double)boxArea.bottom() / pageHeight;
183
184
185
186
187
        
        QString linkText = dviLink.linkText;
        if ( linkText.startsWith("#") )
            linkText = linkText.mid( 1 );
        Anchor anch = m_dviRenderer->findAnchor( linkText );
Pino Toscano's avatar
Pino Toscano committed
188

Pino Toscano's avatar
Pino Toscano committed
189
        Okular::Action *okuLink = 0;
190

191
192
        /* distinguish between local (-> anchor) and remote links */
        if (anch.isValid())
Pino Toscano's avatar
Pino Toscano committed
193
        {
194
            /* internal link */
195
            Okular::DocumentViewport vp;
196
197
            fillViewportFromAnchor( vp, anch, pageWidth, pageHeight );

198
            okuLink = new Okular::GotoAction( "", vp );
Pino Toscano's avatar
Pino Toscano committed
199
200
201
        }
        else
        {
202
            okuLink = new Okular::BrowseAction( dviLink.linkText );
Pino Toscano's avatar
Pino Toscano committed
203
        }
204
205
        if ( okuLink ) 
        {
206
207
            Okular::ObjectRect *orlink = new Okular::ObjectRect( nl, nt, nr, nb, 
                                        false, Okular::ObjectRect::Action, okuLink );
208
209
            dviLinks.push_front( orlink );
        }
210

Pino Toscano's avatar
Pino Toscano committed
211
212
213
214
    }
    return dviLinks; 
}

215
QImage DviGenerator::image( Okular::PixmapRequest *request )
Pino Toscano's avatar
Pino Toscano committed
216
217
218
219
{

    dviPageInfo *pageInfo = new dviPageInfo();
    pageSize ps;
220
    QImage ret;
Pino Toscano's avatar
Pino Toscano committed
221

222
223
    pageInfo->width = request->width();
    pageInfo->height = request->height();
Pino Toscano's avatar
Pino Toscano committed
224

Tobias Koenig's avatar
Tobias Koenig committed
225
    pageInfo->pageNumber = request->pageNumber() + 1;
Pino Toscano's avatar
Pino Toscano committed
226
227
228

//  pageInfo->resolution = m_resolution;

229
230
    QMutexLocker lock( userMutex() );

231
232
233
    if ( m_dviRenderer )
    {
        SimplePageSize s = m_dviRenderer->sizeOfPage( pageInfo->pageNumber );
Pino Toscano's avatar
Pino Toscano committed
234

235
236
237
/*       if ( s.width() != pageInfo->width) */
        //   if (!useDocumentSpecifiedSize)
        //    s = userPreferredSize;
Pino Toscano's avatar
Pino Toscano committed
238

239
240
241
242
        if (s.isValid())
        {
            ps = s; /* it should be the user specified size, if any, instead */
        }
Pino Toscano's avatar
Pino Toscano committed
243

244
        pageInfo->resolution = (double)(pageInfo->width)/ps.width().getLength_in_inch();
Pino Toscano's avatar
Pino Toscano committed
245
246

#if 0
247
248
249
250
        kDebug(DviDebug) << *request
        << ", res:" << pageInfo->resolution << " - (" << pageInfo->width << ","
        << ps.width().getLength_in_inch() << ")," << ps.width().getLength_in_mm()
        << endl;
Pino Toscano's avatar
Pino Toscano committed
251
252
253
254
255
256
#endif

        m_dviRenderer->drawPage( pageInfo );

        if ( ! pageInfo->img.isNull() )
        {
257
            kDebug(DviDebug) << "Image OK";
Pino Toscano's avatar
Pino Toscano committed
258

259
            ret = pageInfo->img;
Pino Toscano's avatar
Pino Toscano committed
260

261
262
263
264
265
            if ( !m_linkGenerated[ request->pageNumber() ] )
            {
                request->page()->setObjectRects( generateDviLinks( pageInfo ) );
                m_linkGenerated[ request->pageNumber() ] = true;
            }
Pino Toscano's avatar
Pino Toscano committed
266
267
268
        }
    }

269
    lock.unlock();
Pino Toscano's avatar
Pino Toscano committed
270
271
272

    delete pageInfo;

273
    return ret;
Pino Toscano's avatar
Pino Toscano committed
274
275
}

276
Okular::TextPage* DviGenerator::textPage( Okular::Page *page )
Pino Toscano's avatar
Pino Toscano committed
277
{
278
    kDebug(DviDebug);
Pino Toscano's avatar
Pino Toscano committed
279
280
    dviPageInfo *pageInfo = new dviPageInfo();
    pageSize ps;
281
282
283
    
    pageInfo->width=page->width();
    pageInfo->height=page->height();
Pino Toscano's avatar
Pino Toscano committed
284
285
286
287

    pageInfo->pageNumber = page->number() + 1;

    pageInfo->resolution = m_resolution;
288
289
290

    QMutexLocker lock( userMutex() );

Pino Toscano's avatar
Pino Toscano committed
291
    // get page text from m_dviRenderer
292
    Okular::TextPage *ktp = 0;
Pino Toscano's avatar
Pino Toscano committed
293
294
    if ( m_dviRenderer )
    {
295
296
297
        SimplePageSize s = m_dviRenderer->sizeOfPage( pageInfo->pageNumber );
        pageInfo->resolution = (double)(pageInfo->width)/ps.width().getLength_in_inch();

Pino Toscano's avatar
Pino Toscano committed
298
        m_dviRenderer->getText( pageInfo );
299
        lock.unlock();
Pino Toscano's avatar
Pino Toscano committed
300

301
        ktp = extractTextFromPage( pageInfo );
Pino Toscano's avatar
Pino Toscano committed
302
303
    }
    delete pageInfo;
304
    return ktp;
Pino Toscano's avatar
Pino Toscano committed
305
306
}

307
Okular::TextPage *DviGenerator::extractTextFromPage( dviPageInfo *pageInfo )
Pino Toscano's avatar
Pino Toscano committed
308
{
309
    QList<Okular::TextEntity*> textOfThePage;
Pino Toscano's avatar
Pino Toscano committed
310

311
312
    QVector<TextBox>::ConstIterator it = pageInfo->textBoxList.constBegin();
    QVector<TextBox>::ConstIterator itEnd = pageInfo->textBoxList.constEnd();
Pino Toscano's avatar
Pino Toscano committed
313
314
    QRect tmpRect;

315
    int pageWidth = pageInfo->width, pageHeight = pageInfo->height;
Pino Toscano's avatar
Pino Toscano committed
316
317
318
319

    for ( ; it != itEnd ; ++it )
    {
        TextBox curTB = *it;
320
 
Pino Toscano's avatar
Pino Toscano committed
321
#if 0
322
        kDebug(DviDebug) << "orientation: " << orientation
Pino Toscano's avatar
Pino Toscano committed
323
324
325
326
327
                 << ", curTB.box: " << curTB.box
                 << ", tmpRect: " << tmpRect 
                 << ", ( " << pageWidth << "," << pageHeight << " )" 
               <<endl;
#endif
328
        textOfThePage.push_back( new Okular::TextEntity( curTB.text,
329
              new Okular::NormalizedRect( curTB.box, pageWidth, pageHeight ) ) );
Pino Toscano's avatar
Pino Toscano committed
330
331
    }

332
    Okular::TextPage* ktp = new Okular::TextPage( textOfThePage );
Pino Toscano's avatar
Pino Toscano committed
333
334
335
336

    return ktp;
}

337
const Okular::DocumentInfo *DviGenerator::generateDocumentInfo()
Pino Toscano's avatar
Pino Toscano committed
338
339
340
341
{
    if ( m_docInfo )
        return m_docInfo;

342
    m_docInfo = new Okular::DocumentInfo();
Pino Toscano's avatar
Pino Toscano committed
343

344
    m_docInfo->set( Okular::DocumentInfo::MimeType, "application/x-dvi" );
Pino Toscano's avatar
Pino Toscano committed
345

346
347
    QMutexLocker lock( userMutex() );

Pino Toscano's avatar
Pino Toscano committed
348
349
350
351
352
353
354
355
    if ( m_dviRenderer && m_dviRenderer->dviFile )
    {
        dvifile *dvif = m_dviRenderer->dviFile;

        // read properties from dvif
        //m_docInfo->set( "filename", dvif->filename, i18n("Filename") );
        m_docInfo->set( "generatorDate", dvif->generatorString,
                       i18n("Generator/Date") );
356
        m_docInfo->set( Okular::DocumentInfo::Pages, QString::number( dvif->total_pages ) );
Pino Toscano's avatar
Pino Toscano committed
357
358
359
360
    }
    return m_docInfo;
}

361
const Okular::DocumentSynopsis *DviGenerator::generateDocumentSynopsis()
362
363
364
365
{
    if ( m_docSynopsis )
        return m_docSynopsis;

366
    m_docSynopsis = new Okular::DocumentSynopsis();
367

368
369
    userMutex()->lock();

370
    QVector<PreBookmark> prebookmarks = m_dviRenderer->getPrebookmarks();
371

372
373
    userMutex()->unlock();

374
375
376
    if ( prebookmarks.isEmpty() ) 
        return m_docSynopsis;

377
378
    QStack<QDomElement> stack;

Laurent Montel's avatar
Laurent Montel committed
379
380
    QVector<PreBookmark>::ConstIterator it = prebookmarks.constBegin();
    QVector<PreBookmark>::ConstIterator itEnd = prebookmarks.constEnd();
381
382
    for( ; it != itEnd; ++it ) 
    {
383
        QDomElement domel = m_docSynopsis->createElement( (*it).title );
384
385
386
        Anchor a = m_dviRenderer->findAnchor((*it).anchorName);
        if ( a.isValid() )
        {
387
            Okular::DocumentViewport vp;
388
 
389
            const Okular::Page *p = document()->page( a.page - 1 );
390
391

            fillViewportFromAnchor( vp, a, (int)p->width(), (int)p->height() );
392
            domel.setAttribute( "Viewport", vp.toString() );
393
394
        }
        if ( stack.isEmpty() )
395
            m_docSynopsis->appendChild( domel );
396
397
        else 
        {
398
            stack.top().appendChild( domel );
399
400
401
402
403
404
405
406
407
            stack.pop();
        }
        for ( int i = 0; i < (*it).noOfChildren; ++i )
            stack.push( domel );
    }

    return m_docSynopsis;
}

408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
Okular::FontInfo::List DviGenerator::fontsForPage( int page )
{
    Q_UNUSED( page );

    Okular::FontInfo::List list;

    // the list of the fonts is extracted once 
    if ( m_fontExtracted )
        return list;

    if ( m_dviRenderer && m_dviRenderer->dviFile &&
         m_dviRenderer->dviFile->font_pool )
    {
        QList<TeXFontDefinition*> fonts = m_dviRenderer->dviFile->font_pool->fontList;

        foreach (const TeXFontDefinition* font, fonts)
        {
            Okular::FontInfo of;
            QString name;
            int zoom = (int)(font->enlargement*100 + 0.5);
Pino Toscano's avatar
Pino Toscano committed
428
#ifdef HAVE_FREETYPE
429
430
431
432
433
434
435
436
437
438
439
440
441
            if ( font->getFullFontName().isEmpty() ) 
            {
                name = QString( "%1, %2%" )
                        .arg( font->fontname )
                        .arg( zoom );
            }
            else
            {
                name = QString( "%1 (%2), %3%" ) 
                        .arg( font->fontname )
                        .arg( font->getFullFontName() ) 
                        .arg( zoom ); 
            }
Pino Toscano's avatar
Pino Toscano committed
442
443
444
445
446
#else
            name = QString( "%1, %2%" )
                    .arg( font->fontname )
                    .arg( zoom );
#endif
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
            of.setName( name );

            QString fontFileName;
            if (!(font->flags & TeXFontDefinition::FONT_VIRTUAL)) {
                if ( font->font != 0 )
                    fontFileName = font->font->errorMessage;
                else
                    fontFileName = i18n("Font file not found");

                if ( fontFileName.isEmpty() )
                    fontFileName = font->filename;
            }

            of.setFile( fontFileName );

            Okular::FontInfo::FontType ft;
            switch ( font->getFontType() )
            {
                case TeXFontDefinition::TEX_PK:
                    ft = Okular::FontInfo::TeXPK;
                    break;
                case TeXFontDefinition::TEX_VIRTUAL:
                    ft = Okular::FontInfo::TeXVirtual;
                    break;
                case TeXFontDefinition::TEX_FONTMETRIC:
                    ft = Okular::FontInfo::TeXFontMetric;
                    break;
                case TeXFontDefinition::FREETYPE:
                    ft = Okular::FontInfo::TeXFreeTypeHandled;
                    break;
            }
            of.setType( ft );

            // DVI has not the concept of "font embedding"
            of.setEmbedType( Okular::FontInfo::NotEmbedded );
            of.setCanBeExtracted( false );

            list.append( of );
        }

        m_fontExtracted = true;

    }

    return list;
}

494
void DviGenerator::loadPages( QVector< Okular::Page * > &pagesVector )
Pino Toscano's avatar
Pino Toscano committed
495
496
497
498
499
500
{
    QSize pageRequiredSize;

    int numofpages = m_dviRenderer->dviFile->total_pages;
    pagesVector.resize( numofpages );

501
502
    m_linkGenerated.fill( false, numofpages );

503
    //kDebug(DviDebug) << "resolution:" << m_resolution << ", dviFile->preferred?";
Pino Toscano's avatar
Pino Toscano committed
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518

    /* get the suggested size */
    if ( m_dviRenderer->dviFile->suggestedPageSize )
    {
        pageRequiredSize = m_dviRenderer->dviFile->suggestedPageSize->sizeInPixel(
               m_resolution );
    }
    else
    {
        pageSize ps;
        pageRequiredSize = ps.sizeInPixel( m_resolution );
    }

    for ( int i = 0; i < numofpages; ++i )
    {
519
        //kDebug(DviDebug) << "getting status of page" << i << ":";
Pino Toscano's avatar
Pino Toscano committed
520
521
522
523
524
525

        if ( pagesVector[i] )
        {
            delete pagesVector[i];
        }

526
        Okular::Page * page = new Okular::Page( i,
Pino Toscano's avatar
Pino Toscano committed
527
528
                                        pageRequiredSize.width(),
                                        pageRequiredSize.height(),
529
530
                                        Okular::Rotation0 );

Pino Toscano's avatar
Pino Toscano committed
531
532
        pagesVector[i] = page;
    }
533
    kDebug(DviDebug) << "pagesVector successfully inizialized!";
534
535
536
537
538
539
540
541
542

    // filling the pages with the source references rects
    const QVector<DVI_SourceFileAnchor>& sourceAnchors = m_dviRenderer->sourceAnchors();
    QVector< QLinkedList< Okular::SourceRefObjectRect * > > refRects( numofpages );
    foreach ( const DVI_SourceFileAnchor& sfa, sourceAnchors )
    {
        if ( sfa.page < 1 || (int)sfa.page > numofpages )
            continue;

543
        Okular::NormalizedPoint p( -1.0, (double)sfa.distance_from_top.getLength_in_pixel( Okular::Utils::dpiY() ) / (double)pageRequiredSize.height() );
544
545
546
547
548
549
        Okular::SourceReference * sourceRef = new Okular::SourceReference( sfa.fileName, sfa.line );
        refRects[ sfa.page - 1 ].append( new Okular::SourceRefObjectRect( p, sourceRef ) );
    }
    for ( int i = 0; i < refRects.size(); ++i )
        if ( !refRects.at(i).isEmpty() )
            pagesVector[i]->setSourceReferences( refRects.at(i) );
Pino Toscano's avatar
Pino Toscano committed
550
551
}

552
553
554
555
556
557
558
559
560
561
bool DviGenerator::print( QPrinter& printer )
{
    // Create tempfile to write to
    KTemporaryFile tf;
    tf.setSuffix( ".ps" );
    if ( !tf.open() )
        return false;

    QList<int> pageList = Okular::FilePrinter::pageList( printer, 
                                 m_dviRenderer->totalPages(),
562
                                 document()->currentPage() + 1,
563
564
565
566
567
568
569
570
571
572
573
574
575
                                 document()->bookmarkedPageList() );
    QString pages;
    QStringList printOptions;
    // List of pages to print.
    foreach ( int p, pageList )
    {
        pages += QString(",%1").arg(p);
    }
    if ( !pages.isEmpty() )
        printOptions << "-pp" << pages.mid(1);

    QEventLoop el;
    m_dviRenderer->setEventLoop( &el );
576
    m_dviRenderer->exportPS( tf.fileName(), printOptions, &printer, document()->orientation() );
577
578
579
580
581
582
583

    tf.close();

    // Error messages are handled by the generator - ugly, but it works.
    return true; 
}

Pino Toscano's avatar
Pino Toscano committed
584
585
586
587
588
589
590
591
592
593
QVariant DviGenerator::metaData( const QString & key, const QVariant & option ) const
{
    if ( key == "NamedViewport" && !option.toString().isEmpty() )
    {
        const Anchor anchor = m_dviRenderer->parseReference( option.toString() );
        if ( anchor.isValid() )
        {
            const Okular::Page *page = document()->page( anchor.page - 1 );
            Q_ASSERT_X( page, "DviGenerator::metaData()", "NULL page as result of valid Anchor" );
            Okular::DocumentViewport viewport;
594
            fillViewportFromAnchor( viewport, anchor, page );
Pino Toscano's avatar
Pino Toscano committed
595
596
597
598
599
600
601
602
            if ( viewport.isValid() )
            {
                return viewport.toString();
            }
        }
    }
    return QVariant();
}
603

Pino Toscano's avatar
Pino Toscano committed
604
#include "generator_dvi.moc"