⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 generator_pdf.cpp

📁 okular
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*************************************************************************** *   Copyright (C) 2004-2006 by Albert Astals Cid <tsdgeos@terra.es>       * *   Copyright (C) 2004 by Enrico Ros <eros.kde@email.it>                  * *                                                                         * *   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.                                   * ***************************************************************************/// qt/kde includes#include <qfile.h>#include <qimage.h>#include <qregexp.h>#include <qtextstream.h>#include <kauthorized.h>#include <klocale.h>#include <kpassworddialog.h>#include <kwallet.h>#include <kprinter.h>#include <ktempfile.h>#include <kmessagebox.h>#include <kdebug.h>// local includes#include "generator_pdf.h"#include "core/observer.h" //for PAGEVIEW_ID#include "core/page.h"#include "core/annotations.h"#include "core/pagetransition.h"#include "settings.h"#include <config.h>#include <config-okular.h>class PDFEmbeddedFile : public EmbeddedFile{    public:        PDFEmbeddedFile(Poppler::EmbeddedFile *f) : ef(f)        {        }                QString name() const        {            return ef->name();        }                QString description() const        {            return ef->description();        }                QByteArray data() const        {            return ef->data();        }                QDateTime modificationDate() const        {            return ef->modDate();        }                QDateTime creationDate() const        {            return ef->createDate();        }        private:        Poppler::EmbeddedFile *ef;};static void fillViewportFromLinkDestination( DocumentViewport &viewport, const Poppler::LinkDestination &destination, const Poppler::Document *pdfdoc ){    viewport.pageNumber = destination.pageNumber() - 1;    if (viewport.pageNumber == -1) return;    // get destination position    // TODO add other attributes to the viewport (taken from link)//     switch ( destination->getKind() )//     {//         case destXYZ:            if (destination.isChangeLeft() || destination.isChangeTop())            {                Poppler::Page *page = pdfdoc->page( viewport.pageNumber );                // TODO remember to change this if we implement DPI and/or rotation                double left, top;                left = destination.left();                top = destination.top();                QSize pageSize = page->pageSize();                delete page;                viewport.rePos.normalizedX = (double)left / (double)pageSize.width();                viewport.rePos.normalizedY = (double)top / (double)pageSize.height();                viewport.rePos.enabled = true;                viewport.rePos.pos = DocumentViewport::TopLeft;            }            /* TODO            if ( dest->getChangeZoom() )                make zoom change*//*        break;        default:            // implement the others cases        break;*///     }}static KPDFLink* createKPDFLinkFromPopplerLink(const Poppler::Link *popplerLink, const Poppler::Document *pdfdoc){	KPDFLink *kpdfLink = 0;	const Poppler::LinkGoto *popplerLinkGoto;	const Poppler::LinkExecute *popplerLinkExecute;	const Poppler::LinkBrowse *popplerLinkBrowse;	const Poppler::LinkAction *popplerLinkAction;	DocumentViewport viewport;		switch(popplerLink->linkType())	{		case Poppler::Link::None:		break;			case Poppler::Link::Goto:			popplerLinkGoto = static_cast<const Poppler::LinkGoto *>(popplerLink);			fillViewportFromLinkDestination( viewport, popplerLinkGoto->destination(), pdfdoc );			kpdfLink = new KPDFLinkGoto(popplerLinkGoto->fileName(), viewport);		break;				case Poppler::Link::Execute:			popplerLinkExecute = static_cast<const Poppler::LinkExecute *>(popplerLink);			kpdfLink = new KPDFLinkExecute( popplerLinkExecute->fileName(), popplerLinkExecute->parameters() );		break;				case Poppler::Link::Browse:			popplerLinkBrowse = static_cast<const Poppler::LinkBrowse *>(popplerLink);			kpdfLink = new KPDFLinkBrowse( popplerLinkBrowse->url() );		break;				case Poppler::Link::Action:			popplerLinkAction = static_cast<const Poppler::LinkAction *>(popplerLink);			kpdfLink = new KPDFLinkAction( (KPDFLinkAction::ActionType)popplerLinkAction->actionType() );		break;				case Poppler::Link::Movie:			// not implemented		break;	}		return kpdfLink;}static QLinkedList<ObjectRect*> generateKPDFLinks( const QList<Poppler::Link*> &popplerLinks, int width, int height, const Poppler::Document *pdfdoc ){	QLinkedList<ObjectRect*> kpdfLinks;	foreach(const Poppler::Link *popplerLink, popplerLinks)	{		QRectF linkArea = popplerLink->linkArea();		double nl = linkArea.left() / (double)width,		       nt = linkArea.top() / (double)height,		       nr = linkArea.right() / (double)width,		       nb = linkArea.bottom() / (double)height;		// create the rect using normalized coords and attach the KPDFLink to it		ObjectRect * rect = new ObjectRect( nl, nt, nr, nb, false, ObjectRect::Link, createKPDFLinkFromPopplerLink(popplerLink, pdfdoc) );		// add the ObjectRect to the container		kpdfLinks.push_front( rect );	}	qDeleteAll(popplerLinks);	return kpdfLinks;}/** NOTES on threading: * internal: thread race prevention is done via the 'docLock' mutex. the *           mutex is needed only because we have the asynchronous thread; else *           the operations are all within the 'gui' thread, scheduled by the *           Qt scheduler and no mutex is needed. * external: dangerous operations are all locked via mutex internally, and the *           only needed external thing is the 'canGeneratePixmap' method *           that tells if the generator is free (since we don't want an *           internal queue to store PixmapRequests). A generatedPixmap call *           without the 'ready' flag set, results in undefined behavior. * So, as example, printing while generating a pixmap asynchronously is safe, * it might only block the gui thread by 1) waiting for the mutex to unlock * in async thread and 2) doing the 'heavy' print operation. */OKULAR_EXPORT_PLUGIN(PDFGenerator)PDFGenerator::PDFGenerator( KPDFDocument * doc )    : Generator( doc ), pdfdoc( 0 ), ready( true ),    pixmapRequest( 0 ), docInfoDirty( true ), docSynopsisDirty( true ),    docFontsDirty( true ), docEmbeddedFilesDirty( true ){    // update the configuration    reparseConfig();    // generate the pixmapGeneratorThread    generatorThread = new PDFPixmapGeneratorThread( this );    connect(generatorThread, SIGNAL(finished()), this, SLOT(threadFinished()), Qt::QueuedConnection);}PDFGenerator::~PDFGenerator(){    // stop and delete the generator thread    if ( generatorThread )    {        generatorThread->wait();        delete generatorThread;    }}void PDFGenerator::setOrientation(QVector<KPDFPage*> & pagesVector, int orientation){    loadPages(pagesVector,orientation,true);}//BEGIN Generator inherited functionsbool PDFGenerator::loadDocument( const QString & filePath, QVector<KPDFPage*> & pagesVector ){#ifndef NDEBUG    if ( pdfdoc )    {        kDebug() << "PDFGenerator: multiple calls to loadDocument. Check it." << endl;        return false;    }#endif    // create PDFDoc for the given file    pdfdoc = Poppler::Document::load( filePath, 0, 0 );    // if the file didn't open correctly it might be encrypted, so ask for a pass    bool firstInput = true;    bool triedWallet = false;    KWallet::Wallet * wallet = 0;    while ( !pdfdoc && pdfdoc->isLocked() )    {        QByteArray password;        // 1.A. try to retrieve the first password from the kde wallet system        if ( !triedWallet )        {            QString walletName = KWallet::Wallet::NetworkWallet();            wallet = KWallet::Wallet::openWallet( walletName );            if ( wallet )            {                // use the KPdf folder (and create if missing)                if ( !wallet->hasFolder( "KPdf" ) )                    wallet->createFolder( "KPdf" );                wallet->setFolder( "KPdf" );                // look for the pass in that folder                QString retrievedPass;                if ( !wallet->readPassword( filePath.section('/', -1, -1), retrievedPass ) )                    password = retrievedPass.toLocal8Bit();            }            triedWallet = true;        }        // 1.B. if not retrieved, ask the password using the kde password dialog        if ( password.isNull() )        {            QString prompt;            if ( firstInput )                prompt = i18n( "Please insert the password to read the document:" );            else                prompt = i18n( "Incorrect password. Try again:" );            firstInput = false;            // if the user presses cancel, abort opening            if ( KPasswordDialog::getPassword( 0, password, prompt ) != KPasswordDialog::Accepted )                break;        }        // 2. reopen the document using the password        pdfdoc->unlock( password, password );        // 3. if the password is correct, store it to the wallet        if ( !pdfdoc->isLocked() && wallet && /*safety check*/ wallet->isOpen() )        {            QString goodPass = QString::fromLocal8Bit( password.data() );            wallet->writePassword( filePath.section('/', -1, -1), goodPass );        }    }    if ( !pdfdoc )    {        pdfdoc = 0;        return false;    }    // build Pages (currentPage was set -1 by deletePages)    uint pageCount = pdfdoc->numPages();    pagesVector.resize(pageCount);    loadPages(pagesVector, 0, false);    // the file has been loaded correctly    return true;}Poppler::Annotation* getPopplerAnnot(Annotation* ann){    if(!ann)        return NULL;    Poppler::Annotation* resannot;    if(ann->subType()==Annotation::AText)    {        TextAnnotation * a=(TextAnnotation *)ann;        Poppler::TextAnnotation * t=new Poppler::TextAnnotation();        resannot=t;        t->textType = (Poppler::TextAnnotation::TextType)a->textType;        t->textIcon = a->textIcon;        t->textFont = a->textFont;        t->inplaceAlign = a->inplaceAlign;        t->inplaceText = a->inplaceText;        t->inplaceIntent = (Poppler::TextAnnotation::InplaceIntent)a->inplaceIntent;        for(int i=0;i<3;i++)        {            t->inplaceCallout[i] = QPointF(a->inplaceCallout[i].x, a->inplaceCallout[i].y);        }    }    else if(ann->subType()==Annotation::ALine)    {        LineAnnotation *a = (LineAnnotation *)ann;        Poppler::LineAnnotation * t=new Poppler::LineAnnotation();        resannot=t;        foreach(NormalizedPoint pt, a->linePoints)        {            t->linePoints.append(QPointF(pt.x, pt.y));        }        t->lineStartStyle = (Poppler::LineAnnotation::TermStyle)a->lineStartStyle;        t->lineEndStyle = (Poppler::LineAnnotation::TermStyle)a->lineEndStyle;        t->lineClosed = a->lineClosed;        t->lineInnerColor = a->lineInnerColor;        t->lineLeadingFwdPt = a->lineLeadingFwdPt;        t->lineLeadingBackPt = a->lineLeadingBackPt;        t->lineShowCaption = a->lineShowCaption;        t->lineIntent =  (Poppler::LineAnnotation::LineIntent)a->lineIntent;    }    else if(ann->subType()==Annotation::AGeom)    {        GeomAnnotation *a = (GeomAnnotation*) ann;        Poppler::GeomAnnotation * t=new Poppler::GeomAnnotation();        resannot=t;        t->geomType = (Poppler::GeomAnnotation::GeomType)a->geomType;        t->geomInnerColor = a->geomInnerColor;        t->geomWidthPt = a->geomWidthPt;    }    else if(ann->subType()==Annotation::AHighlight)    {        HighlightAnnotation *a = (HighlightAnnotation*) ann;        Poppler::HighlightAnnotation * t=new Poppler::HighlightAnnotation();        resannot=t;        t->highlightType = (Poppler::HighlightAnnotation::HighlightType)a->highlightType;        foreach(HighlightAnnotation::Quad ua, a->highlightQuads)        {            Poppler::HighlightAnnotation::Quad ut;            for(int i=0;i<4;i++)            {                ut.points[i]=QPointF(ua.points[i].x,ua.points[i].y);            }            ut.capStart=ua.capStart;            ut.capEnd=ua.capEnd;            ut.feather=ua.feather;            t->highlightQuads.append(ut);        }    }    else if(ann->subType()==Annotation::AStamp)    {        StampAnnotation *a=(StampAnnotation*)ann;        Poppler::StampAnnotation * t=new Poppler::StampAnnotation();        resannot=t;                t->stampIconName = a->stampIconName;    }    else if(ann->subType()==Annotation::AInk)    {        InkAnnotation *a=(InkAnnotation*)ann;        Poppler::InkAnnotation * t=new Poppler::InkAnnotation();        resannot=t;        foreach(QLinkedList<NormalizedPoint> alist, a->inkPaths)        {            QLinkedList<QPointF> lt;            foreach(NormalizedPoint pa, alist)            {                lt.append(QPointF(pa.x,pa.y));            }            t->inkPaths.append(lt);        }    }    else    {        resannot=new Poppler::Annotation();    }    //COMMON params:    resannot->author=ann->author;    resannot->contents=ann->contents;    resannot->uniqueName=ann->uniqueName;    resannot->modifyDate=ann->modifyDate;    resannot->creationDate=ann->creationDate;    resannot->flags=ann->flags;    resannot->boundary=QRectF(ann->boundary.left,ann->boundary.top,                              ann->boundary.right,ann->boundary.bottom);    resannot->style.color=ann->style.color;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -