mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Rendering tool + benchmarking tool
This commit is contained in:
@ -374,7 +374,7 @@ public:
|
||||
|
||||
/// Font cache which caches both fonts, and realized fonts. Cache has individual limit
|
||||
/// for fonts, and realized fonts.
|
||||
class PDFFontCache
|
||||
class PDFFORQTLIBSHARED_EXPORT PDFFontCache
|
||||
{
|
||||
public:
|
||||
inline explicit PDFFontCache(size_t fontCacheLimit, size_t realizedFontCacheLimit) :
|
||||
|
@ -400,7 +400,7 @@ void PDFRasterizerPool::render(const std::vector<PDFInteger>& pageIndices,
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
emit renderError(PDFRenderError(RenderErrorType::Information, PDFTranslationContext::tr("Start at %1...").arg(QTime::currentTime().toString(Qt::TextDate))));
|
||||
emit renderError(PDFCatalog::INVALID_PAGE_INDEX, PDFRenderError(RenderErrorType::Information, PDFTranslationContext::tr("Start at %1...").arg(QTime::currentTime().toString(Qt::TextDate))));
|
||||
|
||||
if (progress)
|
||||
{
|
||||
@ -419,19 +419,27 @@ void PDFRasterizerPool::render(const std::vector<PDFInteger>& pageIndices,
|
||||
{
|
||||
progress->step();
|
||||
}
|
||||
emit renderError(PDFRenderError(RenderErrorType::Error, PDFTranslationContext::tr("Page %1 not found.").arg(pageIndex)));
|
||||
emit renderError(pageIndex, PDFRenderError(RenderErrorType::Error, PDFTranslationContext::tr("Page %1 not found.").arg(pageIndex)));
|
||||
return;
|
||||
}
|
||||
|
||||
QElapsedTimer totalPageTimer;
|
||||
totalPageTimer.start();
|
||||
|
||||
QElapsedTimer pageTimer;
|
||||
pageTimer.start();
|
||||
|
||||
// Precompile the page
|
||||
PDFPrecompiledPage precompiledPage;
|
||||
PDFCMSPointer cms = m_cmsManager->getCurrentCMS();
|
||||
PDFRenderer renderer(m_document, m_fontCache, cms.data(), m_optionalContentActivity, m_features, m_meshQualitySettings);
|
||||
renderer.compile(&precompiledPage, pageIndex);
|
||||
|
||||
for (const PDFRenderError error : precompiledPage.getErrors())
|
||||
qint64 pageCompileTime = pageTimer.restart();
|
||||
|
||||
for (const PDFRenderError& error : precompiledPage.getErrors())
|
||||
{
|
||||
emit renderError(PDFRenderError(error.type, PDFTranslationContext::tr("Page %1: %2").arg(pageIndex + 1).arg(error.message)));
|
||||
emit renderError(pageIndex, error);
|
||||
}
|
||||
|
||||
// We can const-cast here, because we do not modify the document in annotation manager.
|
||||
@ -443,12 +451,22 @@ void PDFRasterizerPool::render(const std::vector<PDFInteger>& pageIndices,
|
||||
annotationManager.setDocument(modifiedDocument);
|
||||
|
||||
// Render page to image
|
||||
pageTimer.restart();
|
||||
PDFRasterizer* rasterizer = acquire();
|
||||
qint64 pageWaitTime = pageTimer.restart();
|
||||
QImage image = rasterizer->render(pageIndex, page, &precompiledPage, imageSizeGetter(page), m_features, &annotationManager);
|
||||
qint64 pageRenderTime = pageTimer.elapsed();
|
||||
release(rasterizer);
|
||||
|
||||
// Now, process the image
|
||||
processImage(pageIndex, qMove(image));
|
||||
PDFRenderedPageImage renderedPageImage;
|
||||
renderedPageImage.pageIndex = pageIndex;
|
||||
renderedPageImage.pageImage = qMove(image);
|
||||
renderedPageImage.pageCompileTime = pageCompileTime;
|
||||
renderedPageImage.pageWaitTime = pageWaitTime;
|
||||
renderedPageImage.pageRenderTime = pageRenderTime;
|
||||
renderedPageImage.pageTotalTime = totalPageTimer.elapsed();
|
||||
processImage(renderedPageImage);
|
||||
|
||||
if (progress)
|
||||
{
|
||||
@ -462,14 +480,19 @@ void PDFRasterizerPool::render(const std::vector<PDFInteger>& pageIndices,
|
||||
progress->finish();
|
||||
}
|
||||
|
||||
emit renderError(PDFRenderError(RenderErrorType::Information, PDFTranslationContext::tr("Finished at %1...").arg(QTime::currentTime().toString(Qt::TextDate))));
|
||||
emit renderError(PDFRenderError(RenderErrorType::Information, PDFTranslationContext::tr("%1 miliseconds elapsed to render %2 pages...").arg(timer.nsecsElapsed() / 1000000).arg(pageIndices.size())));
|
||||
emit renderError(PDFCatalog::INVALID_PAGE_INDEX, PDFRenderError(RenderErrorType::Information, PDFTranslationContext::tr("Finished at %1...").arg(QTime::currentTime().toString(Qt::TextDate))));
|
||||
emit renderError(PDFCatalog::INVALID_PAGE_INDEX, PDFRenderError(RenderErrorType::Information, PDFTranslationContext::tr("%1 miliseconds elapsed to render %2 pages...").arg(timer.nsecsElapsed() / 1000000).arg(pageIndices.size())));
|
||||
}
|
||||
|
||||
int PDFRasterizerPool::getDefaultRasterizerCount()
|
||||
{
|
||||
int hint = QThread::idealThreadCount() / 2;
|
||||
return qBound(1, hint, 16);
|
||||
return getCorrectedRasterizerCount(hint);
|
||||
}
|
||||
|
||||
int PDFRasterizerPool::getCorrectedRasterizerCount(int rasterizerCount)
|
||||
{
|
||||
return qBound(1, rasterizerCount, 16);
|
||||
}
|
||||
|
||||
PDFImageWriterSettings::PDFImageWriterSettings()
|
||||
@ -833,7 +856,7 @@ std::vector<PDFInteger> PDFPageImageExportSettings::getPages() const
|
||||
return result;
|
||||
}
|
||||
|
||||
QString PDFPageImageExportSettings::getOutputFileName(PDFInteger pageIndex, const QByteArray& outputFormat)
|
||||
QString PDFPageImageExportSettings::getOutputFileName(PDFInteger pageIndex, const QByteArray& outputFormat) const
|
||||
{
|
||||
QString fileName = m_fileTemplate;
|
||||
fileName.replace('%', QString::number(pageIndex + 1));
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <QSemaphore>
|
||||
#include <QImageWriter>
|
||||
#include <QSurfaceFormat>
|
||||
#include <QImage>
|
||||
|
||||
class QPainter;
|
||||
class QOpenGLContext;
|
||||
@ -168,6 +169,17 @@ private:
|
||||
QOpenGLFramebufferObject* m_fbo;
|
||||
};
|
||||
|
||||
/// Simple structure for storing rendered page images
|
||||
struct PDFRenderedPageImage
|
||||
{
|
||||
qint64 pageCompileTime = 0;
|
||||
qint64 pageWaitTime = 0;
|
||||
qint64 pageRenderTime = 0;
|
||||
qint64 pageTotalTime = 0;
|
||||
PDFInteger pageIndex;
|
||||
QImage pageImage;
|
||||
};
|
||||
|
||||
/// Pool of page image renderers. It can use predefined number of renderers to
|
||||
/// render page images asynchronously. You can use this object in two ways -
|
||||
/// first one is as standard object pool, second one is to directly render
|
||||
@ -181,8 +193,9 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
|
||||
using PageImageSizeGetter = std::function<QSize(const PDFPage*)>;
|
||||
using ProcessImageMethod = std::function<void(PDFInteger, QImage&&)>;
|
||||
using ProcessImageMethod = std::function<void(PDFRenderedPageImage&)>;
|
||||
|
||||
/// Creates new rasterizer pool
|
||||
/// \param document Document
|
||||
@ -229,8 +242,15 @@ public:
|
||||
/// Returns default rasterizer count
|
||||
static int getDefaultRasterizerCount();
|
||||
|
||||
/// Returns corrected rasterizer count (so, if user
|
||||
/// select too high or too low rasterizer count, this function
|
||||
/// corrects it to acceptable number.
|
||||
/// \param rasterizerCount Requested number of rasterizers
|
||||
/// \returns Corrected number of rasterizers
|
||||
static int getCorrectedRasterizerCount(int rasterizerCount);
|
||||
|
||||
signals:
|
||||
void renderError(PDFRenderError error);
|
||||
void renderError(PDFInteger pageIndex, PDFRenderError error);
|
||||
|
||||
private:
|
||||
const PDFDocument* m_document;
|
||||
@ -344,7 +364,7 @@ public:
|
||||
std::vector<PDFInteger> getPages() const;
|
||||
|
||||
/// Returns output file name for given page
|
||||
QString getOutputFileName(PDFInteger pageIndex, const QByteArray& outputFormat);
|
||||
QString getOutputFileName(PDFInteger pageIndex, const QByteArray& outputFormat) const;
|
||||
|
||||
static constexpr int getMinDPIResolution() { return 72; }
|
||||
static constexpr int getMaxDPIResolution() { return 6000; }
|
||||
|
Reference in New Issue
Block a user