mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-01-29 16:49:32 +01:00
Asynchronous image redraw
This commit is contained in:
parent
f020098435
commit
9da1efe4ef
@ -22,6 +22,9 @@
|
|||||||
#include "pdfrenderer.h"
|
#include "pdfrenderer.h"
|
||||||
#include "pdfdrawspacecontroller.h"
|
#include "pdfdrawspacecontroller.h"
|
||||||
|
|
||||||
|
#include <QCloseEvent>
|
||||||
|
#include <QtConcurrent/QtConcurrent>
|
||||||
|
|
||||||
namespace pdfplugin
|
namespace pdfplugin
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -30,7 +33,9 @@ OutputPreviewDialog::OutputPreviewDialog(const pdf::PDFDocument* document, pdf::
|
|||||||
ui(new Ui::OutputPreviewDialog),
|
ui(new Ui::OutputPreviewDialog),
|
||||||
m_inkMapper(document),
|
m_inkMapper(document),
|
||||||
m_document(document),
|
m_document(document),
|
||||||
m_widget(widget)
|
m_widget(widget),
|
||||||
|
m_needUpdateImage(false),
|
||||||
|
m_futureWatcher(nullptr)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
@ -39,7 +44,7 @@ OutputPreviewDialog::OutputPreviewDialog(const pdf::PDFDocument* document, pdf::
|
|||||||
ui->pageIndexScrollBar->setMaximum(int(document->getCatalog()->getPageCount()));
|
ui->pageIndexScrollBar->setMaximum(int(document->getCatalog()->getPageCount()));
|
||||||
|
|
||||||
m_inkMapper.createSpotColors(true);
|
m_inkMapper.createSpotColors(true);
|
||||||
updateImage();
|
updatePageImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputPreviewDialog::~OutputPreviewDialog()
|
OutputPreviewDialog::~OutputPreviewDialog()
|
||||||
@ -50,25 +55,67 @@ OutputPreviewDialog::~OutputPreviewDialog()
|
|||||||
void OutputPreviewDialog::resizeEvent(QResizeEvent* event)
|
void OutputPreviewDialog::resizeEvent(QResizeEvent* event)
|
||||||
{
|
{
|
||||||
QDialog::resizeEvent(event);
|
QDialog::resizeEvent(event);
|
||||||
updateImage();
|
updatePageImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutputPreviewDialog::updateImage()
|
void OutputPreviewDialog::closeEvent(QCloseEvent* event)
|
||||||
{
|
{
|
||||||
|
if (!isRenderingDone())
|
||||||
|
{
|
||||||
|
event->ignore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutputPreviewDialog::showEvent(QShowEvent* event)
|
||||||
|
{
|
||||||
|
Q_UNUSED(event);
|
||||||
|
|
||||||
|
updatePageImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutputPreviewDialog::updatePageImage()
|
||||||
|
{
|
||||||
|
if (!isRenderingDone())
|
||||||
|
{
|
||||||
|
m_needUpdateImage = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_needUpdateImage = false;
|
||||||
|
|
||||||
const pdf::PDFPage* page = m_document->getCatalog()->getPage(ui->pageIndexScrollBar->value() - 1);
|
const pdf::PDFPage* page = m_document->getCatalog()->getPage(ui->pageIndexScrollBar->value() - 1);
|
||||||
if (!page)
|
if (!page)
|
||||||
{
|
{
|
||||||
ui->imageLabel->setPixmap(QPixmap());
|
ui->imageLabel->setPixmap(QPixmap());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
|
|
||||||
|
QSize renderSize = ui->imageLabel->size();
|
||||||
|
auto renderImage = [this, page, renderSize]() -> RenderedImage
|
||||||
|
{
|
||||||
|
return renderPage(page, renderSize);
|
||||||
|
};
|
||||||
|
|
||||||
|
m_future = QtConcurrent::run(renderImage);
|
||||||
|
m_futureWatcher = new QFutureWatcher<RenderedImage>();
|
||||||
|
connect(m_futureWatcher, &QFutureWatcher<RenderedImage>::finished, this, &OutputPreviewDialog::onPageImageRendered);
|
||||||
|
m_futureWatcher->setFuture(m_future);
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputPreviewDialog::RenderedImage OutputPreviewDialog::renderPage(const pdf::PDFPage* page, QSize renderSize)
|
||||||
|
{
|
||||||
|
RenderedImage result;
|
||||||
|
|
||||||
QRectF pageRect = page->getRotatedMediaBox();
|
QRectF pageRect = page->getRotatedMediaBox();
|
||||||
QSizeF pageSize = pageRect.size();
|
QSizeF pageSize = pageRect.size();
|
||||||
pageSize.scale(ui->imageLabel->width(), ui->imageLabel->height(), Qt::KeepAspectRatio);
|
pageSize.scale(renderSize.width(), renderSize.height(), Qt::KeepAspectRatio);
|
||||||
QSize imageSize = pageSize.toSize();
|
QSize imageSize = pageSize.toSize();
|
||||||
|
|
||||||
if (!imageSize.isValid())
|
if (!imageSize.isValid())
|
||||||
{
|
{
|
||||||
ui->imageLabel->setPixmap(QPixmap());
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
pdf::PDFTransparencyRendererSettings settings;
|
pdf::PDFTransparencyRendererSettings settings;
|
||||||
@ -88,7 +135,31 @@ void OutputPreviewDialog::updateImage()
|
|||||||
renderer.endPaint();
|
renderer.endPaint();
|
||||||
|
|
||||||
QImage image = renderer.toImage(false, true, pdf::PDFRGB{ 1.0f, 1.0f, 1.0f });
|
QImage image = renderer.toImage(false, true, pdf::PDFRGB{ 1.0f, 1.0f, 1.0f });
|
||||||
ui->imageLabel->setPixmap(QPixmap::fromImage(image));
|
|
||||||
|
result.image = qMove(image);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutputPreviewDialog::onPageImageRendered()
|
||||||
|
{
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
|
||||||
|
RenderedImage result = m_future.result();
|
||||||
|
m_future = QFuture<RenderedImage>();
|
||||||
|
m_futureWatcher->deleteLater();
|
||||||
|
m_futureWatcher = nullptr;
|
||||||
|
|
||||||
|
ui->imageLabel->setPixmap(QPixmap::fromImage(result.image));
|
||||||
|
|
||||||
|
if (m_needUpdateImage)
|
||||||
|
{
|
||||||
|
updatePageImage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OutputPreviewDialog::isRenderingDone() const
|
||||||
|
{
|
||||||
|
return !(m_futureWatcher && m_futureWatcher->isRunning());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace pdfplugin
|
} // namespace pdfplugin
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
#include "pdftransparencyrenderer.h"
|
#include "pdftransparencyrenderer.h"
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
#include <QFuture>
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
@ -41,14 +43,29 @@ public:
|
|||||||
virtual ~OutputPreviewDialog() override;
|
virtual ~OutputPreviewDialog() override;
|
||||||
|
|
||||||
virtual void resizeEvent(QResizeEvent* event) override;
|
virtual void resizeEvent(QResizeEvent* event) override;
|
||||||
|
virtual void closeEvent(QCloseEvent* event) override;
|
||||||
|
virtual void showEvent(QShowEvent* event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateImage();
|
|
||||||
|
struct RenderedImage
|
||||||
|
{
|
||||||
|
QImage image;
|
||||||
|
};
|
||||||
|
|
||||||
|
void updatePageImage();
|
||||||
|
void onPageImageRendered();
|
||||||
|
RenderedImage renderPage(const pdf::PDFPage* page, QSize renderSize);
|
||||||
|
bool isRenderingDone() const;
|
||||||
|
|
||||||
Ui::OutputPreviewDialog* ui;
|
Ui::OutputPreviewDialog* ui;
|
||||||
pdf::PDFInkMapper m_inkMapper;
|
pdf::PDFInkMapper m_inkMapper;
|
||||||
const pdf::PDFDocument* m_document;
|
const pdf::PDFDocument* m_document;
|
||||||
pdf::PDFWidget* m_widget;
|
pdf::PDFWidget* m_widget;
|
||||||
|
bool m_needUpdateImage;
|
||||||
|
|
||||||
|
QFuture<RenderedImage> m_future;
|
||||||
|
QFutureWatcher<RenderedImage>* m_futureWatcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
Loading…
x
Reference in New Issue
Block a user