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

📄 generator_pdf.cpp

📁 okular
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    docLock.lock();    QList<Poppler::FontInfo> fonts = pdfdoc->fonts();    docLock.unlock();    const QString fontTypeNames[8] = {        i18n("unknown"),        i18n("Type 1"),        i18n("Type 1C"),        i18n("Type 3"),        i18n("TrueType"),        i18n("CID Type 0"),        i18n("CID Type 0C"),        i18n("CID TrueType")    };        foreach (const Poppler::FontInfo &font, fonts)    {        // 0. add font element        QDomElement fontElem = docFonts.createElement( "font" );        docFonts.firstChild().appendChild( fontElem );        // 1. set Name        const QString &name = font.name();        fontElem.setAttribute( "Name", name.isNull() ? i18n("[none]") : name );        // 2. set Type        fontElem.setAttribute( "Type", fontTypeNames[ font.type() ] );        // 3. set Embedded        fontElem.setAttribute( "Embedded", font.isEmbedded() ? i18n("Yes") : i18n("No") );        // 4. set Path        fontElem.setAttribute( "File", font.file() );    }    return &docFonts;}const QList<EmbeddedFile*> *PDFGenerator::embeddedFiles(){    if (docEmbeddedFilesDirty)    {        docLock.lock();        const QList<Poppler::EmbeddedFile*> &popplerFiles = pdfdoc->embeddedFiles();        foreach(Poppler::EmbeddedFile* pef, popplerFiles)        {            docEmbeddedFiles.append(new PDFEmbeddedFile(pef));        }        docLock.unlock();                docEmbeddedFilesDirty = false;    }        return &docEmbeddedFiles;}bool PDFGenerator::isAllowed( int permissions ){#if !OKULAR_FORCE_DRM    if (KAuthorized::authorize("skip_drm") && !KpdfSettings::obeyDRM()) return true;#endif    bool b = true;    if (permissions & KPDFDocument::AllowModify) b = b && pdfdoc->okToChange();    if (permissions & KPDFDocument::AllowCopy) b = b && pdfdoc->okToCopy();    if (permissions & KPDFDocument::AllowPrint) b = b && pdfdoc->okToPrint();    if (permissions & KPDFDocument::AllowNotes) b = b && pdfdoc->okToAddNotes();    return b;}bool PDFGenerator::canGeneratePixmap( bool /* async */){    return ready;}void PDFGenerator::generatePixmap( PixmapRequest * request ){#ifndef NDEBUG    if ( !ready )        kDebug() << "calling generatePixmap() when not in READY state!" << endl;#endif    // update busy state (not really needed here, because the flag needs to    // be set only to prevent asking a pixmap while the thread is running)    ready = false;    // debug requests to this (xpdf) generator    //kDebug() << "id: " << request->id << " is requesting " << (request->async ? "ASYNC" : "sync") <<  " pixmap for page " << request->page->number() << " [" << request->width << " x " << request->height << "]." << endl;    /** asynchronous requests (generation in PDFPixmapGeneratorThread::run() **/    if ( request->async )    {        // start the generation into the thread        generatorThread->startGeneration( request );        return;    }    /** synchronous request: in-place generation **/    // compute dpi used to get an image with desired width and height    KPDFPage * page = request->page;    double fakeDpiX = request->width * 72.0 / page->width(),           fakeDpiY = request->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() && (request->width == page->width()) &&                       (request->height == page->height());    // generate links and image rects if rendering pages on pageview    bool genObjectRects = request->id & (PAGEVIEW_ID | PRESENTATION_ID);    // 0. LOCK [waits for the thread end]    docLock.lock();    // 1. Set OutputDev parameters and Generate contents    // note: thread safety is set on 'false' for the GUI (this) thread    Poppler::Page *p = pdfdoc->page(page->number());    // 2. Take data from outputdev and attach it to the Page    page->setPixmap( request->id, p->splashRenderToPixmap(fakeDpiX, fakeDpiY, -1, -1, -1, -1, genObjectRects, (Poppler::Page::Rotation)m_document->rotation()) );        if ( genObjectRects )    {    	// TODO previously we extracted Image type rects too, but that needed porting to poppler        // and as we are not doing anything with Image type rects i did not port it, have a look at        // dead gp_outputdev.cpp on image extraction        page->setObjectRects( generateKPDFLinks(p->links(), request->width, request->height, pdfdoc) );    }    // 3. UNLOCK [re-enables shared access]    docLock.unlock();    if ( genTextPage )    {        QList<Poppler::TextBox*> textList = p->textList((Poppler::Page::Rotation)m_document->rotation());        page->setSearchPage( abstractTextPage(textList, page->height(), page->width(), page->orientation()) );        qDeleteAll(textList);    }    delete p;        // update ready state    ready = true;    // notify the new generation    signalRequestDone( request );}bool PDFGenerator::canGenerateTextPage(){    return true;}void PDFGenerator::generateSyncTextPage( KPDFPage * page ){// TODO i think this is wrong because we need the "optative rotation", not the original rotation, but AFAIK it's never called    kDebug() << "calling generateSyncTextPage( KPDFPage * page )" << endl;    // build a TextList...    Poppler::Page *pp = pdfdoc->page( page->number() );    docLock.lock();    QList<Poppler::TextBox*> textList = pp->textList((Poppler::Page::Rotation)m_document->rotation());    docLock.unlock();    delete pp;    // ..and attach it to the page    page->setSearchPage( abstractTextPage(textList, page->height(), page->width(), page->orientation()) );    qDeleteAll(textList);}bool PDFGenerator::print( KPrinter& printer ){    int width, height;    QString ps = printer.option("PageSize");    if (ps.indexOf(QRegExp("w\\d+h\\d+")) == 0)    {        // size not supported by Qt, KPrinter gives us the size as wWIDTHhHEIGHT        // remove the w        ps = ps.mid(1);        int hPos = ps.indexOf("h");        width = ps.left(hPos).toInt();        height = ps.mid(hPos+1).toInt();    }    else    {        // size is supported by Qt, we get either the pageSize name or nothing because the default pageSize is used        QPrinter dummy(QPrinter::PrinterResolution);        dummy.setFullPage(true);        dummy.setPageSize((QPrinter::PageSize)(ps.isEmpty() ? KGlobal::locale()->pageSize() : pageNameToPageSize(ps)));        width = dummy.width();        height = dummy.height();    }    KTempFile tf( QString::null, ".ps" );    QList<int> pageList;    if (!printer.previewOnly()) pageList = printer.pageList();    else for(int i = 1; i <= pdfdoc->numPages(); i++) pageList.push_back(i);        docLock.lock();    // TODO rotation    if (pdfdoc->print(tf.name(), pageList, 72, 72, 0, width, height))    {        docLock.unlock();        printer.printFiles(QStringList(tf.name()), true);        return true;    }    else    {        docLock.unlock();        return false;    }	return false;}QString PDFGenerator::getMetaData( const QString & key, const QString & option ){    if ( key == "StartFullScreen" )    {        // asking for the 'start in fullscreen mode' (pdf property)        if ( pdfdoc->pageMode() == Poppler::Document::FullScreen )            return "yes";    }    else if ( key == "NamedViewport" && !option.isEmpty() )    {        // asking for the page related to a 'named link destination'. the        // option is the link name. @see addSynopsisChildren.        DocumentViewport viewport;        docLock.lock();        Poppler::LinkDestination *ld = pdfdoc->linkDestination( option );        docLock.unlock();        if ( ld )        {            fillViewportFromLinkDestination( viewport, *ld, pdfdoc );        }        delete ld;        if ( viewport.pageNumber >= 0 )            return viewport.toString();    }    else if ( key == "DocumentTitle" )    {        docLock.lock();        QString title = pdfdoc->info( "Title" );        docLock.unlock();        return title;    }    return QString();}bool PDFGenerator::reparseConfig(){    // load paper color from Settings or use the white default color    QColor color = ( (KpdfSettings::renderMode() == KpdfSettings::EnumRenderMode::Paper ) &&                     KpdfSettings::changeColors() ) ? KpdfSettings::paperColor() : Qt::white;    // if paper color is changed we have to rebuild every visible pixmap in addition    // to the outputDevice. it's the 'heaviest' case, other effect are just recoloring    // over the page rendered on 'standard' white background.    if ( pdfdoc && color != pdfdoc->paperColor() )    {        docLock.lock();        pdfdoc->setPaperColor(color);        docLock.unlock();        return true;    }    return false;}bool PDFGenerator::exportToText( const QString & fileName ){    QFile f( fileName );    if ( !f.open( QIODevice::WriteOnly ) )        return false;    QTextStream ts( &f );    int num = m_document->pages();    for ( int i = 0; i < num; ++i )    {        docLock.lock();        Poppler::Page *pp = pdfdoc->page(i);        QString text = pp->text(QRect());        docLock.unlock();        ts << text;        delete pp;    }    f.close();    return true;}//END Generator inherited functionsinline void append (KPDFTextPage* ktp,    QString s, double l, double b, double r, double t){//       kWarning() << "text: " << s << " at (" << l << "," << t << ")x(" << r <<","<<b<<")" << endl;                ktp->append( s ,                    new NormalizedRect(                    l,                    t,                    r,                    b                    ));}KPDFTextPage * PDFGenerator::abstractTextPage(const QList<Poppler::TextBox*> &text, double height, double width,int rot){        KPDFTextPage* ktp=new KPDFTextPage;    Poppler::TextBox *next;     kWarning() << "getting text page in generator pdf - rotation: " << rot << endl;    int charCount=0;    int j;    QString s;    NormalizedRect * wordRect = new NormalizedRect;        rot = (rot + m_document->rotation()) % 4;        foreach (Poppler::TextBox *word, text)    {        wordRect->left = word->boundingBox().left();        wordRect->bottom = word->boundingBox().bottom();        wordRect->right = word->boundingBox().right();        wordRect->top = word->boundingBox().top();        charCount=word->text().length();        next=word->nextWord();        switch (rot)        {            case 0:            // 0 degrees, normal word boundaries are top and bottom            // only x boundaries change the order of letters is normal not reversed            for (j = 0; j < charCount; j++)            {                s = word->text().at(j);                append(ktp, (j==charCount-1 && !next ) ? (s + '\n') : s,                    // this letters boundary                    word->edge(j)/width,                    wordRect->bottom/height,                    // next letters boundary                    word->edge(j+1)/width,                    wordRect->top/height);            }                        if ( word->hasSpaceAfter() && next )              append(ktp, " ",                    // this letters boundary                     word->edge(charCount)/width,                     wordRect->bottom/height,                    // next letters boundary                     next->edge(0)/width,                     wordRect->top/height);            break;            case 1:            // 90 degrees, x boundaries not changed            // y ones change, the order of letters is normal not reversed            for (j=0;j<charCount;j++)            {                s=word->text().at(j);                append(ktp, (j==charCount-1 && !next ) ? (s + '\n') : s,                    wordRect->left/width,                    word->edge(j)/height,                    wordRect->right/width,                    word->edge(j+1)/height);            }                        if ( word->hasSpaceAfter() && next )              append(ktp, " ",                    // this letters boundary                     wordRect->left/width,                     word->edge(charCount)/height,                    // next letters boundary                     wordRect->right/width,                     next->edge(0)/height);            break;            case 2:            // same as case 0 but reversed order of letters            for (j=0;j<charCount;j++)            {                s=word->text().at(j);                append(ktp, (j==charCount-1 && !next ) ? (s + '\n') : s,                    word->edge(j+1)/width,                    wordRect->bottom/height,                    word->edge(j)/width,                    wordRect->top/height);            }                        if ( word->hasSpaceAfter() && next )              append(ktp, " ",                    // this letters boundary                     next->edge(0)/width,                     wordRect->bottom/height,                    // next letters boundary                     word->edge(charCount)/width,                     wordRect->top/height);                       break;            case 3:            for (j=0;j<charCount;j++)            {                s=word->text().at(j);                append(ktp, (j==charCount-1 && !next ) ? (s + '\n') : s,                    wordRect->left/width,                    word->edge(j+1)/height,

⌨️ 快捷键说明

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