mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Ink management in output preview
This commit is contained in:
@@ -32,6 +32,7 @@ OutputPreviewDialog::OutputPreviewDialog(const pdf::PDFDocument* document, pdf::
|
||||
QDialog(parent, Qt::Dialog | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint),
|
||||
ui(new Ui::OutputPreviewDialog),
|
||||
m_inkMapper(document),
|
||||
m_inkMapperForRendering(document),
|
||||
m_document(document),
|
||||
m_widget(widget),
|
||||
m_needUpdateImage(false),
|
||||
@@ -43,8 +44,17 @@ OutputPreviewDialog::OutputPreviewDialog(const pdf::PDFDocument* document, pdf::
|
||||
ui->pageIndexScrollBar->setValue(1);
|
||||
ui->pageIndexScrollBar->setMaximum(int(document->getCatalog()->getPageCount()));
|
||||
|
||||
m_inkMapper.createSpotColors(true);
|
||||
m_inkMapper.createSpotColors(ui->simulateSeparationsCheckBox->isChecked());
|
||||
connect(ui->simulateSeparationsCheckBox, &QCheckBox::clicked, this, &OutputPreviewDialog::onSimulateSeparationsChecked);
|
||||
connect(ui->simulatePaperColorCheckBox, &QCheckBox::clicked, this, &OutputPreviewDialog::onSimulatePaperColorChecked);
|
||||
connect(ui->redPaperColorEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &OutputPreviewDialog::onPaperColorChanged);
|
||||
connect(ui->greenPaperColorEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &OutputPreviewDialog::onPaperColorChanged);
|
||||
connect(ui->bluePaperColorEdit, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &OutputPreviewDialog::onPaperColorChanged);
|
||||
connect(ui->inksTreeWidget->model(), &QAbstractItemModel::dataChanged, this, &OutputPreviewDialog::onInksChanged);
|
||||
|
||||
updatePageImage();
|
||||
updateInks();
|
||||
updatePaperColorWidgets();
|
||||
}
|
||||
|
||||
OutputPreviewDialog::~OutputPreviewDialog()
|
||||
@@ -73,6 +83,106 @@ void OutputPreviewDialog::showEvent(QShowEvent* event)
|
||||
updatePageImage();
|
||||
}
|
||||
|
||||
void OutputPreviewDialog::updateInks()
|
||||
{
|
||||
ui->inksTreeWidget->setUpdatesEnabled(false);
|
||||
ui->inksTreeWidget->clear();
|
||||
|
||||
QTreeWidgetItem* processColorsRoot = new QTreeWidgetItem(ui->inksTreeWidget, QStringList(tr("Process Inks")));
|
||||
QTreeWidgetItem* spotColorsRoot = new QTreeWidgetItem(ui->inksTreeWidget, QStringList(tr("Spot Inks")));
|
||||
|
||||
processColorsRoot->setFlags(processColorsRoot->flags() | Qt::ItemIsUserCheckable);
|
||||
processColorsRoot->setCheckState(0, Qt::Checked);
|
||||
|
||||
spotColorsRoot->setFlags(spotColorsRoot->flags() | Qt::ItemIsUserCheckable);
|
||||
spotColorsRoot->setCheckState(0, Qt::Checked);
|
||||
|
||||
int colorIndex = 0;
|
||||
std::vector<pdf::PDFInkMapper::ColorInfo> separations = m_inkMapper.getSeparations(4);
|
||||
for (const auto& colorInfo : separations)
|
||||
{
|
||||
QTreeWidgetItem* item = nullptr;
|
||||
if (!colorInfo.isSpot)
|
||||
{
|
||||
// Process color (ink)
|
||||
item = new QTreeWidgetItem(processColorsRoot, QStringList(colorInfo.textName));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Spot color (ink)
|
||||
item = new QTreeWidgetItem(spotColorsRoot, QStringList(colorInfo.textName));
|
||||
}
|
||||
|
||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||
item->setCheckState(0, Qt::Checked);
|
||||
item->setData(0, Qt::UserRole, colorIndex++);
|
||||
}
|
||||
|
||||
if (processColorsRoot->childCount() == 0)
|
||||
{
|
||||
delete processColorsRoot;
|
||||
}
|
||||
|
||||
if (spotColorsRoot->childCount() == 0)
|
||||
{
|
||||
delete spotColorsRoot;
|
||||
}
|
||||
|
||||
ui->inksTreeWidget->expandAll();
|
||||
ui->inksTreeWidget->setUpdatesEnabled(true);
|
||||
}
|
||||
|
||||
void OutputPreviewDialog::updatePaperColorWidgets()
|
||||
{
|
||||
const bool isPaperColorEnabled = ui->simulatePaperColorCheckBox->isChecked();
|
||||
|
||||
ui->redPaperColorEdit->setEnabled(isPaperColorEnabled);
|
||||
ui->greenPaperColorEdit->setEnabled(isPaperColorEnabled);
|
||||
ui->bluePaperColorEdit->setEnabled(isPaperColorEnabled);
|
||||
|
||||
if (!isPaperColorEnabled)
|
||||
{
|
||||
ui->redPaperColorEdit->setValue(1.0);
|
||||
ui->greenPaperColorEdit->setValue(1.0);
|
||||
ui->bluePaperColorEdit->setValue(1.0);
|
||||
}
|
||||
}
|
||||
|
||||
void OutputPreviewDialog::onPaperColorChanged()
|
||||
{
|
||||
const bool isPaperColorEnabled = ui->simulatePaperColorCheckBox->isChecked();
|
||||
if (isPaperColorEnabled)
|
||||
{
|
||||
updatePageImage();
|
||||
}
|
||||
}
|
||||
|
||||
void OutputPreviewDialog::onSimulateSeparationsChecked(bool checked)
|
||||
{
|
||||
m_inkMapper.setSpotColorsActive(checked);
|
||||
updateInks();
|
||||
updatePageImage();
|
||||
}
|
||||
|
||||
void OutputPreviewDialog::onSimulatePaperColorChecked(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked);
|
||||
|
||||
updatePaperColorWidgets();
|
||||
updatePageImage();
|
||||
}
|
||||
|
||||
void OutputPreviewDialog::onInksChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles)
|
||||
{
|
||||
Q_UNUSED(topLeft);
|
||||
Q_UNUSED(bottomRight);
|
||||
|
||||
if (roles.contains(Qt::CheckStateRole))
|
||||
{
|
||||
updatePageImage();
|
||||
}
|
||||
}
|
||||
|
||||
void OutputPreviewDialog::updatePageImage()
|
||||
{
|
||||
if (!isRenderingDone())
|
||||
@@ -92,10 +202,46 @@ void OutputPreviewDialog::updatePageImage()
|
||||
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
||||
QSize renderSize = ui->imageLabel->size();
|
||||
auto renderImage = [this, page, renderSize]() -> RenderedImage
|
||||
pdf::PDFRGB paperColor = pdf::PDFRGB{ 1.0f, 1.0f, 1.0f };
|
||||
|
||||
// Active color mask
|
||||
uint32_t activeColorMask = pdf::PDFPixelFormat::getAllColorsMask();
|
||||
|
||||
const int itemCount = ui->inksTreeWidget->topLevelItemCount();
|
||||
for (int i = 0; i < itemCount; ++i)
|
||||
{
|
||||
return renderPage(page, renderSize);
|
||||
QTreeWidgetItem* rootItem = ui->inksTreeWidget->topLevelItem(i);
|
||||
const bool isRootItemChecked = rootItem->data(0, Qt::CheckStateRole).toInt() == Qt::Checked;
|
||||
|
||||
const int childCount = rootItem->childCount();
|
||||
for (int j = 0; j < childCount; ++j)
|
||||
{
|
||||
QTreeWidgetItem* childItem = rootItem->child(j);
|
||||
const bool isChecked = childItem->data(0, Qt::CheckStateRole).toInt() == Qt::Checked;
|
||||
const bool isEnabled = isRootItemChecked && isChecked;
|
||||
|
||||
if (!isEnabled)
|
||||
{
|
||||
uint32_t colorIndex = childItem->data(0, Qt::UserRole).toInt();
|
||||
uint32_t colorFlags = 1 << colorIndex;
|
||||
activeColorMask = activeColorMask & ~colorFlags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Paper color
|
||||
if (ui->simulatePaperColorCheckBox)
|
||||
{
|
||||
paperColor[0] = ui->redPaperColorEdit->value();
|
||||
paperColor[1] = ui->greenPaperColorEdit->value();
|
||||
paperColor[2] = ui->bluePaperColorEdit->value();
|
||||
}
|
||||
|
||||
m_inkMapperForRendering = m_inkMapper;
|
||||
QSize renderSize = ui->imageLabel->size();
|
||||
auto renderImage = [this, page, renderSize, paperColor, activeColorMask]() -> RenderedImage
|
||||
{
|
||||
return renderPage(page, renderSize, paperColor, activeColorMask);
|
||||
};
|
||||
|
||||
m_future = QtConcurrent::run(renderImage);
|
||||
@@ -104,7 +250,7 @@ void OutputPreviewDialog::updatePageImage()
|
||||
m_futureWatcher->setFuture(m_future);
|
||||
}
|
||||
|
||||
OutputPreviewDialog::RenderedImage OutputPreviewDialog::renderPage(const pdf::PDFPage* page, QSize renderSize)
|
||||
OutputPreviewDialog::RenderedImage OutputPreviewDialog::renderPage(const pdf::PDFPage* page, QSize renderSize, pdf::PDFRGB paperColor, uint32_t activeColorMask)
|
||||
{
|
||||
RenderedImage result;
|
||||
|
||||
@@ -125,16 +271,20 @@ OutputPreviewDialog::RenderedImage OutputPreviewDialog::renderPage(const pdf::PD
|
||||
settings.flags.setFlag(pdf::PDFTransparencyRendererSettings::MultithreadedPathSampler, true);
|
||||
#endif
|
||||
|
||||
settings.flags.setFlag(pdf::PDFTransparencyRendererSettings::ActiveColorMask, activeColorMask != pdf::PDFPixelFormat::getAllColorsMask());
|
||||
settings.activeColorMask = activeColorMask;
|
||||
|
||||
QMatrix pagePointToDevicePoint = pdf::PDFRenderer::createPagePointToDevicePointMatrix(page, QRect(QPoint(0, 0), imageSize));
|
||||
pdf::PDFDrawWidgetProxy* proxy = m_widget->getDrawWidgetProxy();
|
||||
pdf::PDFCMSPointer cms = proxy->getCMSManager()->getCurrentCMS();
|
||||
pdf::PDFTransparencyRenderer renderer(page, m_document, proxy->getFontCache(), cms.data(), proxy->getOptionalContentActivity(), &m_inkMapper, settings, pagePointToDevicePoint);
|
||||
pdf::PDFTransparencyRenderer renderer(page, m_document, proxy->getFontCache(), cms.data(), proxy->getOptionalContentActivity(),
|
||||
&m_inkMapperForRendering, settings, pagePointToDevicePoint);
|
||||
|
||||
renderer.beginPaint(imageSize);
|
||||
renderer.processContents();
|
||||
renderer.endPaint();
|
||||
|
||||
QImage image = renderer.toImage(false, true, pdf::PDFRGB{ 1.0f, 1.0f, 1.0f });
|
||||
QImage image = renderer.toImage(false, true, paperColor);
|
||||
|
||||
result.image = qMove(image);
|
||||
return result;
|
||||
@@ -162,4 +312,24 @@ bool OutputPreviewDialog::isRenderingDone() const
|
||||
return !(m_futureWatcher && m_futureWatcher->isRunning());
|
||||
}
|
||||
|
||||
void OutputPreviewDialog::accept()
|
||||
{
|
||||
if (!isRenderingDone())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void OutputPreviewDialog::reject()
|
||||
{
|
||||
if (!isRenderingDone())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QDialog::reject();
|
||||
}
|
||||
|
||||
} // namespace pdfplugin
|
||||
|
@@ -46,8 +46,19 @@ public:
|
||||
virtual void closeEvent(QCloseEvent* event) override;
|
||||
virtual void showEvent(QShowEvent* event) override;
|
||||
|
||||
virtual void accept() override;
|
||||
virtual void reject() override;
|
||||
|
||||
private:
|
||||
|
||||
void updateInks();
|
||||
void updatePaperColorWidgets();
|
||||
|
||||
void onPaperColorChanged();
|
||||
void onSimulateSeparationsChecked(bool checked);
|
||||
void onSimulatePaperColorChecked(bool checked);
|
||||
void onInksChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles);
|
||||
|
||||
struct RenderedImage
|
||||
{
|
||||
QImage image;
|
||||
@@ -55,11 +66,12 @@ private:
|
||||
|
||||
void updatePageImage();
|
||||
void onPageImageRendered();
|
||||
RenderedImage renderPage(const pdf::PDFPage* page, QSize renderSize);
|
||||
RenderedImage renderPage(const pdf::PDFPage* page, QSize renderSize, pdf::PDFRGB paperColor, uint32_t activeColorMask);
|
||||
bool isRenderingDone() const;
|
||||
|
||||
Ui::OutputPreviewDialog* ui;
|
||||
pdf::PDFInkMapper m_inkMapper;
|
||||
pdf::PDFInkMapper m_inkMapperForRendering;
|
||||
const pdf::PDFDocument* m_document;
|
||||
pdf::PDFWidget* m_widget;
|
||||
bool m_needUpdateImage;
|
||||
|
@@ -64,6 +64,85 @@
|
||||
<property name="title">
|
||||
<string>Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="redLabel">
|
||||
<property name="text">
|
||||
<string>Red</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="blueLabel">
|
||||
<property name="text">
|
||||
<string>Blue</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="greenLabel">
|
||||
<property name="text">
|
||||
<string>Green</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="simulateSeparationsCheckBox">
|
||||
<property name="text">
|
||||
<string>Simulate separations</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="simulatePaperColorCheckBox">
|
||||
<property name="text">
|
||||
<string>Simulate paper color</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QDoubleSpinBox" name="redPaperColorEdit">
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QDoubleSpinBox" name="greenPaperColorEdit">
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QDoubleSpinBox" name="bluePaperColorEdit">
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@@ -73,7 +152,16 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QTreeView" name="treeView"/>
|
||||
<widget class="QTreeWidget" name="inksTreeWidget">
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
Reference in New Issue
Block a user