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

📄 generator_pdf.cpp

📁 okular
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                    wordRect->right/width,                    word->edge(j)/height);            }                        if ( word->hasSpaceAfter() && next )              append(ktp, " ",                    // this letters boundary                     wordRect->left/width,                     next->edge(0)/height,                    // next letters boundary                     wordRect->right/width,                     word->edge(charCount)/height);            break;        }    }    delete wordRect;    return ktp;}void PDFGenerator::addSynopsisChildren( QDomNode * parent, QDomNode * parentDestination ){    // keep track of the current listViewItem    QDomNode n = parent->firstChild();    while( !n.isNull() )    {        // convert the node to an element (sure it is)        QDomElement e = n.toElement();        // The name is the same        QDomElement item = docSyn.createElement( e.tagName() );        parentDestination->appendChild(item);        if (!e.attribute("ExternalFileName").isNull()) item.setAttribute("ExternalFileName", e.attribute("ExternalFileName"));        if (!e.attribute("DestinationName").isNull()) item.setAttribute("ViewportName", e.attribute("DestinationName"));        if (!e.attribute("Destination").isNull())        {            DocumentViewport vp;            fillViewportFromLinkDestination( vp, Poppler::LinkDestination(e.attribute("Destination")), pdfdoc );            item.setAttribute( "Viewport", vp.toString() );        }        // descend recursively and advance to the next node        if ( e.hasChildNodes() ) addSynopsisChildren( &n, &	item );        n = n.nextSibling();    }}void PDFGenerator::addAnnotations( Poppler::Page * popplerPage, KPDFPage * page ){    QList<Poppler::Annotation*> popplerAnnotations = popplerPage->annotations();    foreach(Poppler::Annotation *a, popplerAnnotations)    {        Annotation* ann=getokularAnnot(a);        page->addAnnotation( ann );        //a->window.width = (int)(page->width() * a->window.width);        //a->window.height = (int)(page->height() * a->window.height);        //a->window.width = a->window.width < 200 ? 200 : a->window.width;        // a->window.height = a->window.height < 120 ? 120 : a->window.height;        // resize annotation's geometry to an icon        // TODO okular geom.right = geom.left + 22.0 / page->width();        // TODO okular geom.bottom = geom.top + 22.0 / page->height();                QString szanno;        QTextStream(&szanno)<<"PopplerAnnotation={subType:"<<a->subType()                <<", author:"<<a->author                <<", contents:"<<a->contents                <<", uniqueName:"<<a->uniqueName                <<", modifyDate:"<<a->modifyDate.toString("hh:mm:ss, dd.MM.yyyy")                <<", creationDate:"<<a->creationDate.toString("hh:mm:ss, dd.MM.yyyy")                <<", flags:"<<a->flags                <<", boundary:"<<a->boundary.left()<<","<<a->boundary.top()<<","<<a->boundary.right()<<","<<a->boundary.bottom()                <<", style.color:"<<a->style.color.name()                <<", style.opacity:"<<a->style.opacity                <<", style.width:"<<a->style.width                <<", style.LineStyle:"<<a->style.style                <<", style.xyCorners:"<<a->style.xCorners<<","<<a->style.yCorners                <<", style.marks:"<<a->style.marks                <<", style.spaces:"<<a->style.spaces                <<", style.LineEffect:"<<a->style.effect                <<", style.effectIntensity:"<<a->style.effectIntensity                <<", window.flags:"<<a->window.flags                <<", window.topLeft:"<<(a->window.topLeft.x())                <<","<<(a->window.topLeft.y())                <<", window.width,height:"<<a->window.width<<","<<a->window.height                <<", window.title:"<<a->window.title                <<", window.summary:"<<a->window.summary                <<", window.text:"<<a->window.text;        kDebug( )<<"astario:    "<<szanno<<endl;        // this is uber ugly but i don't know a better way to do it without introducing a poppler::annotation dependency on core        //TODO add annotations after poppler write feather is full suported        /*QDomDocument doc;        QDomElement root = doc.createElement("root");        doc.appendChild(root);        a->store( root, doc );*/    }    qDeleteAll(popplerAnnotations);}void PDFGenerator::addTransition( Poppler::Page * pdfPage, KPDFPage * page )// called on opening when MUTEX is not used{    Poppler::PageTransition *pdfTransition = pdfPage->transition();    if ( !pdfTransition || pdfTransition->type() == Poppler::PageTransition::Replace )        return;    KPDFPageTransition *transition = new KPDFPageTransition();    switch ( pdfTransition->type() ) {        case Poppler::PageTransition::Replace:            // won't get here, added to avoid warning            break;        case Poppler::PageTransition::Split:            transition->setType( KPDFPageTransition::Split );            break;        case Poppler::PageTransition::Blinds:            transition->setType( KPDFPageTransition::Blinds );            break;        case Poppler::PageTransition::Box:            transition->setType( KPDFPageTransition::Box );            break;        case Poppler::PageTransition::Wipe:            transition->setType( KPDFPageTransition::Wipe );            break;        case Poppler::PageTransition::Dissolve:            transition->setType( KPDFPageTransition::Dissolve );            break;        case Poppler::PageTransition::Glitter:            transition->setType( KPDFPageTransition::Glitter );            break;        case Poppler::PageTransition::Fly:            transition->setType( KPDFPageTransition::Fly );            break;        case Poppler::PageTransition::Push:            transition->setType( KPDFPageTransition::Push );            break;        case Poppler::PageTransition::Cover:            transition->setType( KPDFPageTransition::Cover );            break;        case Poppler::PageTransition::Uncover:            transition->setType( KPDFPageTransition::Uncover );            break;        case Poppler::PageTransition::Fade:            transition->setType( KPDFPageTransition::Fade );            break;    }    transition->setDuration( pdfTransition->duration() );    switch ( pdfTransition->alignment() ) {        case Poppler::PageTransition::Horizontal:            transition->setAlignment( KPDFPageTransition::Horizontal );            break;        case Poppler::PageTransition::Vertical:            transition->setAlignment( KPDFPageTransition::Vertical );            break;    }    switch ( pdfTransition->direction() ) {        case Poppler::PageTransition::Inward:            transition->setDirection( KPDFPageTransition::Inward );            break;        case Poppler::PageTransition::Outward:            transition->setDirection( KPDFPageTransition::Outward );            break;    }    transition->setAngle( pdfTransition->angle() );    transition->setScale( pdfTransition->scale() );    transition->setIsRectangular( pdfTransition->isRectangular() );    page->setTransition( transition );}void PDFGenerator::threadFinished(){#if 0    // check if thread is running (has to be stopped now)    if ( generatorThread->running() )    {        // if so, wait for effective thread termination        if ( !generatorThread->wait( 9999 /*10s timeout*/ ) )        {            kWarning() << "PDFGenerator: thread sent 'data available' "                        << "signal but had problems ending." << endl;            return;        }}#endif    // 1. the mutex must be unlocked now    bool isLocked = true;    if (docLock.tryLock()) {        docLock.unlock();        isLocked = false;    }    if ( isLocked )    {        kWarning() << "PDFGenerator: 'data available' but mutex still "                    << "held. Recovering." << endl;        // synchronize GUI thread (must not happen)        docLock.lock();        docLock.unlock();    }    // 2. put thread's generated data into the KPDFPage    PixmapRequest * request = generatorThread->request();    QImage * outImage = generatorThread->takeImage();    QList<Poppler::TextBox*> outText = generatorThread->takeText();    QLinkedList< ObjectRect * > outRects = generatorThread->takeObjectRects();    QPixmap * newpix = new QPixmap();    *newpix = QPixmap::fromImage( *outImage );    request->page->setPixmap( request->id, newpix );    delete outImage;    if ( !outText.isEmpty() )    {        request->page->setSearchPage( abstractTextPage( outText ,             request->page->height(), request->page->width(),request->page->orientation()));        qDeleteAll(outText);    }    bool genObjectRects = request->id & (PAGEVIEW_ID | PRESENTATION_ID);    if (genObjectRects) request->page->setObjectRects( outRects );    // 3. tell generator that data has been taken    generatorThread->endGeneration();    // update ready state    ready = true;    // notify the new generation    signalRequestDone( request );}/** The  PDF Pixmap Generator Thread  **/struct PPGThreadPrivate{    // reference to main objects    PDFGenerator * generator;    PixmapRequest * currentRequest;    // internal temp stored items. don't delete this.    QImage * m_image;    QList<Poppler::TextBox*> m_textList;    QLinkedList< ObjectRect * > m_rects;    bool m_rectsTaken;};PDFPixmapGeneratorThread::PDFPixmapGeneratorThread( PDFGenerator * gen )    : QThread(), d( new PPGThreadPrivate() ){    d->generator = gen;    d->currentRequest = 0;    d->m_image = 0;    d->m_rectsTaken = true;}PDFPixmapGeneratorThread::~PDFPixmapGeneratorThread(){    // delete internal objects if the class is deleted before the gui thread    // takes the data    delete d->m_image;    qDeleteAll(d->m_textList);    if ( !d->m_rectsTaken && d->m_rects.count() )    {        qDeleteAll(d->m_rects);    }    delete d->currentRequest;    // delete internal storage structure    delete d;}void PDFPixmapGeneratorThread::startGeneration( PixmapRequest * request ){#ifndef NDEBUG    // check if a generation is already running    if ( d->currentRequest )    {        kDebug() << "PDFPixmapGeneratorThread: requesting a pixmap "                  << "when another is being generated." << endl;        delete request;        return;    }    // check if the mutex is already held    bool isLocked = true;    if (d->generator->docLock.tryLock()) {        d->generator->docLock.unlock();        isLocked = false;    }    if ( isLocked )    {        kDebug() << "PDFPixmapGeneratorThread: requesting a pixmap "                  << "with the mutex already held." << endl;        delete request;        return;    }#endif    // set generation parameters and run thread    d->currentRequest = request;    start( QThread::InheritPriority );}void PDFPixmapGeneratorThread::endGeneration(){#ifndef NDEBUG    // check if a generation is already running    if ( !d->currentRequest )    {        kDebug() << "PDFPixmapGeneratorThread: 'end generation' called "                  << "but generation was not started." << endl;        return;    }#endif    // reset internal members preparing for a new generation    d->currentRequest = 0;}PixmapRequest *PDFPixmapGeneratorThread::request() const{    return d->currentRequest;}QImage * PDFPixmapGeneratorThread::takeImage() const{    QImage * img = d->m_image;    d->m_image = 0;    return img;}QList<Poppler::TextBox*> PDFPixmapGeneratorThread::takeText(){    QList<Poppler::TextBox*> tl = d->m_textList;    d->m_textList.clear();    return tl;}QLinkedList< ObjectRect * > PDFPixmapGeneratorThread::takeObjectRects() const{    d->m_rectsTaken = true;    return d->m_rects;}void PDFPixmapGeneratorThread::run()// perform contents generation, when the MUTEX is already LOCKED// @see PDFGenerator::generatePixmap( .. ) (and be aware to sync the code){    // compute dpi used to get an image with desired width and height    KPDFPage * page = d->currentRequest->page;    int width = d->currentRequest->width,        height = d->currentRequest->height;    double fakeDpiX = width * 72.0 / page->width(),           fakeDpiY = height * 72.0 / page->height();    // setup kpdf output device: text page is generated only if we are at 72dpi.    // since we can pre-generate the TextPage at the right res.. why not?    bool genTextPage = !page->hasSearchPage() &&                       ( width == page->width() ) &&                       ( height == page->height() );    // generate links and image rects if rendering pages on pageview    bool genObjectRects = d->currentRequest->id & (PAGEVIEW_ID | PRESENTATION_ID);    // 0. LOCK s[tart locking XPDF thread unsafe classes]    d->generator->docLock.lock();    // 1. set OutputDev parameters and Generate contents    Poppler::Page *pp = d->generator->pdfdoc->page( page->number() );        // 2. grab data from the OutputDev and store it locally (note takeIMAGE)#ifndef NDEBUG    if ( d->m_image )        kDebug() << "PDFPixmapGeneratorThread: previous image not taken" << endl;    if ( !d->m_textList.isEmpty() )        kDebug() << "PDFPixmapGeneratorThread: previous text not taken" << endl;#endif    d->m_image = new QImage( pp->splashRenderToImage( fakeDpiX, fakeDpiY, -1, -1, -1, -1, genObjectRects, (Poppler::Page::Rotation)d->currentRequest->documentRotation  ) );        if ( genObjectRects )    {    	d->m_rects = generateKPDFLinks(pp->links(), width, height, d->generator->pdfdoc);    }    else d->m_rectsTaken = false;    if ( genTextPage )    {        d->m_textList = pp->textList((Poppler::Page::Rotation)d->currentRequest->documentRotation);    }    delete pp;        // 3. [UNLOCK] mutex    d->generator->docLock.unlock();    // by ending the thread notifies the GUI thread that data is pending and can be read}#include "generator_pdf.moc"

⌨️ 快捷键说明

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