Beispiel #1
0
bool UBImportPDF::addFileToDocument(UBDocumentProxy* pDocument, const QFile& pFile)
{
    QString documentName = QFileInfo(pFile.fileName()).completeBaseName();

    QUuid uuid = QUuid::createUuid();

    QString filepath = UBPersistenceManager::persistenceManager()->addPdfFileToDocument(pDocument, pFile.fileName(), uuid);

    PDFRenderer *pdfRenderer = PDFRenderer::rendererForUuid(uuid, pDocument->persistencePath() + "/" + filepath); // renderer is automatically deleted when not used anymore

    if (!pdfRenderer->isValid())
    {
        UBApplication::showMessage(tr("PDF import failed."));
        return false;
    }

    int documentPageCount = pDocument->pageCount();

    if (documentPageCount == 1 && UBPersistenceManager::persistenceManager()->loadDocumentScene(pDocument, 0)->isEmpty())
    {
        documentPageCount = 0;
    }

    int pdfPageCount = pdfRenderer->pageCount();

    for(int pdfPageNumber = 1; pdfPageNumber <= pdfPageCount; pdfPageNumber++)
    {
        int pageIndex = documentPageCount + (pdfPageNumber - 1);
        UBApplication::showMessage(tr("Importing page %1 of %2").arg(pdfPageNumber).arg(pdfPageCount), true);

        UBGraphicsScene* scene = 0;

        if (pageIndex == 0)
        {
            scene = UBPersistenceManager::persistenceManager()->loadDocumentScene(pDocument, pageIndex);
        }
        else
        {
            scene = UBPersistenceManager::persistenceManager()->createDocumentSceneAt(pDocument, pageIndex);
        }

        scene->setBackground(false, false);
        UBGraphicsPDFItem *pdfItem = new UBGraphicsPDFItem(pdfRenderer, pdfPageNumber); // deleted by the scene
        scene->addItem(pdfItem);

        pdfItem->setPos(-pdfItem->boundingRect().width() / 2, -pdfItem->boundingRect().height() / 2);

        scene->setAsBackgroundObject(pdfItem, false, false);

        scene->setNominalSize(pdfItem->boundingRect().width(), pdfItem->boundingRect().height());


        UBPersistenceManager::persistenceManager()->persistDocumentScene(pDocument, scene, pageIndex);
    }

    UBApplication::showMessage(tr("PDF import successful."));

    return true;
}
Beispiel #2
0
PDFRenderer* PDFRenderer::rendererForUuid(const QUuid &uuid, const QString &filename, bool importingFile)
{
    if (sRenderers.contains(uuid))
    {
        return sRenderers.value(uuid);
    }
    else
    {
        PDFRenderer *newRenderer = new XPDFRenderer(filename,importingFile);

        newRenderer->setRefCount(0);
        newRenderer->setFileUuid(uuid);

        QFile file(filename);
        file.open(QIODevice::ReadOnly);
        newRenderer->setFileData(file.readAll());
        file.close();

        sRenderers.insert(newRenderer->fileUuid(), newRenderer);

        QDesktopWidget* desktop = UBApplication::desktop();
        int dpiCommon = (desktop->physicalDpiX() + desktop->physicalDpiY()) / 2;
        newRenderer->setDPI(dpiCommon);

        return newRenderer;
    }
}
Beispiel #3
0
QList<UBGraphicsItem*> UBImportPDF::import(const QUuid& uuid, const QString& filePath)
{
    QList<UBGraphicsItem*> result;

    PDFRenderer *pdfRenderer = PDFRenderer::rendererForUuid(uuid, filePath, true); // renderer is automatically deleted when not used anymore

    if (!pdfRenderer->isValid())
    {
        UBApplication::showMessage(tr("PDF import failed."));
        return result;
    }
	pdfRenderer->setDPI(this->dpi);

    int pdfPageCount = pdfRenderer->pageCount();

    for(int pdfPageNumber = 1; pdfPageNumber <= pdfPageCount; pdfPageNumber++)
    {
        UBApplication::showMessage(tr("Importing page %1 of %2").arg(pdfPageNumber).arg(pdfPageCount), true);
        result << new UBGraphicsPDFItem(pdfRenderer, pdfPageNumber); // deleted by the scene
    }
    return result;
}
bool PDFRenderTask::is_page_out_of_date()
{
    // check whether the page is in request list
    bool out_of_date = !(doc_ctrl->get_prerender_policy()->get_requests().contains(
                         page_number));

    if (out_of_date)
    {
        return out_of_date;
    }

    PDFRenderer *renderer = doc_ctrl->get_renderer();
    // check the render setting
    if (page_render_attr.get_zoom_setting() !=
        renderer->get_render_attr().get_zoom_setting() ||
        page_render_attr.get_rotate() !=
        renderer->get_render_attr().get_rotate())
    {
        out_of_date = true;
    }

    return out_of_date;
}
void PDFRenderTask::execute()
{
    // don't execute the prerender task if the page is out of date
    if (is_page_out_of_date())
    {
        return;
    }

    PDFRenderer *renderer = doc_ctrl->get_renderer();

    // estimate whether the page has been cached
    // it is necessary here although there is same estimation
    // in main thread, because the same page might be constructed
    // in other tasks.
    if (page == 0)
    {
        page = doc_ctrl->get_page(page_number);

        if (page == 0)
        {   
            page = renderer->gen_page(page_number, page_render_attr);
        }
    }

    //assert(page);
    if (page == 0)
    {
        ERRORPRINTF("Cannot Create New Page");
        return;
    }

    // set the reference id, this operation is thread-safe now
    // NOTE: this function must be called before setting render attributes
    // because the main thread would update the ref id if the render attributes
    // changes.
    page->set_ref_id(ref_id);

    // if it is ZOOM_AUTO_CROP mode, it means it is necessary to get the content
    // area of the page
    double real_zoom = page_render_attr.get_real_zoom_value();
    if (real_zoom == PLUGIN_ZOOM_TO_CROP_BY_PAGE ||
        real_zoom == PLUGIN_ZOOM_TO_CROP_BY_WIDTH)
    {
        RenderArea content_area;
        if (!page->get_content_area(renderer, content_area))
        {
            ERRORPRINTF("Cannot get content area of page:%d", page_number);
            return;
        }
        PDFRenderAttributes origin_attr = page_render_attr;
        renderer->calc_real_zoom(page_number, origin_attr, page_render_attr);
        real_zoom = page_render_attr.get_real_zoom_value();
    }

    // if the page is cached and the bitmap has been rendered
    // calculate the delta value. Becuase the old bitmap would
    // be destroyed and new one is going to be rendered in the following
    // step
    int page_len = static_cast<int>(page->length());

    page_len = static_cast<int>(PDFPage::try_calc_length(real_zoom,
                                doc_ctrl->get_page_crop_width(page_number),
                                doc_ctrl->get_page_crop_height(page_number))) -
               page_len;

    PDFPage::RenderStatus cur_status = page->get_render_status();
    if (!(page->get_render_attr() == page_render_attr))
    {
        // if the render attributes change, re-render the page
        // DO NOT update the render setting here, because it might
        // change the length of page
        // DO NOT change the status of page at this moment
        cur_status = PDFPage::RENDER_STOP;
    }
    
    bool render_done = true;

    // render bitmap
    if (cur_status != PDFPage::RENDER_DONE)
    {
        TRACE("Task, Render Page:%d, Ref ID:%d, Current Task:%p\n\n", page_number, ref_id, this);
        // update the page cache to make sure there is enough memory
        // if page_len < 0, it means the page is going to shrink, the memory
        // must be enough
        // TODO. Add the page number as one parameter for making enough memory
        // The pages with lower priorites would be released.
        if (page_len > 0 &&
            !PDFLibrary::instance().make_enough_memory(doc_ctrl,
                                                       page_number,
                                                       page_len))
        {
            WARNPRINTF("Cannot make enough memory to implement rendering");

            // notify uds that it is out of memory that the page rendering
            // is aborted
            renderer->handle_page_ready(render_result, page, TASK_RENDER_OOM);
            return;
        }

        // update the render status
        page->set_render_status(cur_status);

        // only set the render attributes
        page->set_render_attr(page_render_attr);

        render_done = page->render_splash_map(renderer
            , static_cast<void*>(this));

        // render the text page when the render is done
        if (render_done)
        {
            page->render_text(renderer);
        }
    }

    if (render_done)
    {
        // set the render status at last
        page->set_render_status(PDFPage::RENDER_DONE);

        if (render_result != 0)
        {
            // set the page into render result
            render_result->set_page(page);
        }

        // notify uds that the page is ready
        renderer->handle_page_ready(render_result, page, TASK_RENDER_DONE);
    }
    else
    {
        if (render_result != 0 && is_aborted())
        {
            // if the task is aborted, set the render result to "Discard"
            render_result->set_discard(true);
        }
        else
        {
            renderer->handle_page_ready(render_result, page, TASK_RENDER_OOM);
        }
    }

}