From e63d5aa24224ab1946b08c548ca4ea50b554298b Mon Sep 17 00:00:00 2001 From: Jakub Melka Date: Sun, 14 Feb 2021 18:38:53 +0100 Subject: [PATCH] Ink management in output preview --- Pdf4QtLib/sources/pdftransparencyrenderer.cpp | 185 ++++++++++++++++-- Pdf4QtLib/sources/pdftransparencyrenderer.h | 35 +++- .../outputpreviewdialog.cpp | 184 ++++++++++++++++- .../OutputPreviewPlugin/outputpreviewdialog.h | 14 +- .../outputpreviewdialog.ui | 90 ++++++++- 5 files changed, 483 insertions(+), 25 deletions(-) diff --git a/Pdf4QtLib/sources/pdftransparencyrenderer.cpp b/Pdf4QtLib/sources/pdftransparencyrenderer.cpp index e0f4038..a3cdd85 100644 --- a/Pdf4QtLib/sources/pdftransparencyrenderer.cpp +++ b/Pdf4QtLib/sources/pdftransparencyrenderer.cpp @@ -641,6 +641,9 @@ void PDFTransparencyRenderer::beginPaint(QSize pixelSize) } m_pageTransparencyGroupGuard.reset(new PDFTransparencyGroupGuard(this, qMove(transparencyGroup))); + m_transparencyGroupDataStack.back().filterColorsUsingMask = (m_settings.flags.testFlag(PDFTransparencyRendererSettings::ActiveColorMask) && + m_settings.activeColorMask != PDFPixelFormat::getAllColorsMask()); + m_transparencyGroupDataStack.back().activeColorMask = m_settings.activeColorMask; } const PDFFloatBitmap& PDFTransparencyRenderer::endPaint() @@ -1093,6 +1096,28 @@ void PDFTransparencyRenderer::performEndTransparencyGroup(ProcessOrder order, co PDFTransparencyGroupPainterData sourceData = qMove(m_transparencyGroupDataStack.back()); m_transparencyGroupDataStack.pop_back(); + // Filter inactive colors - clear all colors in immediate mask, + // which are set to inactive. + if (sourceData.filterColorsUsingMask) + { + const PDFPixelFormat pixelFormat = sourceData.immediateBackdrop.getPixelFormat(); + const uint32_t colorChannelStart = pixelFormat.getColorChannelIndexStart(); + const uint32_t colorChannelEnd = pixelFormat.getColorChannelIndexEnd(); + const uint32_t processColorChannelEnd = pixelFormat.getProcessColorChannelIndexEnd(); + + for (uint32_t colorChannelIndex = colorChannelStart; colorChannelIndex < colorChannelEnd; ++colorChannelIndex) + { + const uint32_t flag = 1 << colorChannelIndex; + if (!(sourceData.activeColorMask & flag)) + { + const bool isProcessColor = colorChannelIndex < processColorChannelEnd; + const bool isSubtractive = isProcessColor ? pixelFormat.hasProcessColorsSubtractive() : pixelFormat.hasSpotColorsSubtractive(); + + sourceData.immediateBackdrop.fillChannel(colorChannelIndex, isSubtractive ? 0.0f : 1.0f); + } + } + } + PDFTransparencyGroupPainterData& targetData = m_transparencyGroupDataStack.back(); sourceData.immediateBackdrop.convertToColorSpace(getCMS(), targetData.renderingIntent, targetData.blendColorSpace, this); @@ -1429,6 +1454,118 @@ PDFInkMapper::PDFInkMapper(const PDFDocument* document) : } +std::vector PDFInkMapper::getSeparations(uint32_t processColorCount) const +{ + std::vector result; + result.reserve(getActiveSpotColorCount() + processColorCount); + + switch (processColorCount) + { + case 1: + { + ColorInfo gray; + gray.name = "Process Gray"; + gray.textName = PDFTranslationContext::tr("Process Gray"); + gray.canBeActive = true; + gray.active = true; + gray.isSpot = false; + result.emplace_back(qMove(gray)); + break; + } + + case 3: + { + ColorInfo red; + red.name = "Process Red"; + red.textName = PDFTranslationContext::tr("Process Red"); + red.canBeActive = true; + red.active = true; + red.isSpot = false; + result.emplace_back(qMove(red)); + + ColorInfo green; + green.name = "Process Green"; + green.textName = PDFTranslationContext::tr("Process Green"); + green.canBeActive = true; + green.active = true; + green.isSpot = false; + result.emplace_back(qMove(green)); + + ColorInfo blue; + blue.name = "Process Blue"; + blue.textName = PDFTranslationContext::tr("Process Blue"); + blue.canBeActive = true; + blue.active = true; + blue.isSpot = false; + result.emplace_back(qMove(blue)); + break; + } + + case 4: + { + ColorInfo cyan; + cyan.name = "Process Cyan"; + cyan.textName = PDFTranslationContext::tr("Process Cyan"); + cyan.canBeActive = true; + cyan.active = true; + cyan.isSpot = false; + result.emplace_back(qMove(cyan)); + + ColorInfo magenta; + magenta.name = "Process Magenta"; + magenta.textName = PDFTranslationContext::tr("Process Magenta"); + magenta.canBeActive = true; + magenta.active = true; + magenta.isSpot = false; + result.emplace_back(qMove(magenta)); + + ColorInfo yellow; + yellow.name = "Process Yellow"; + yellow.textName = PDFTranslationContext::tr("Process Yellow"); + yellow.canBeActive = true; + yellow.active = true; + yellow.isSpot = false; + result.emplace_back(qMove(yellow)); + + ColorInfo black; + black.name = "Process Black"; + black.textName = PDFTranslationContext::tr("Process Black"); + black.canBeActive = true; + black.active = true; + black.isSpot = false; + result.emplace_back(qMove(black)); + break; + } + + default: + { + for (uint32_t i = 0; i < processColorCount; ++i) + { + ColorInfo generic; + generic.textName = PDFTranslationContext::tr("Process Generic%1").arg(i + 1); + generic.name = generic.textName.toLatin1(); + generic.canBeActive = true; + generic.active = true; + generic.isSpot = false; + result.emplace_back(qMove(generic)); + } + } + } + + for (const auto& spotColor : m_spotColors) + { + if (!spotColor.active) + { + // Skip inactive spot colors + continue; + } + + result.emplace_back(spotColor); + } + + return result; +} + void PDFInkMapper::createSpotColors(bool activate) { m_spotColors.clear(); @@ -1477,8 +1614,9 @@ void PDFInkMapper::createSpotColors(bool activate) const QByteArray& colorName = separationColorSpace->getColorName(); if (!containsSpotColor(colorName)) { - SpotColorInfo info; + ColorInfo info; info.name = colorName; + info.textName = PDFEncoding::convertTextString(info.name); info.colorSpace = colorSpacePointer; info.spotColorIndex = uint32_t(m_spotColors.size()); m_spotColors.emplace_back(qMove(info)); @@ -1500,8 +1638,9 @@ void PDFInkMapper::createSpotColors(bool activate) const PDFDeviceNColorSpace::ColorantInfo& colorantInfo = colorants[i]; if (!containsSpotColor(colorantInfo.name)) { - SpotColorInfo info; + ColorInfo info; info.name = colorantInfo.name; + info.textName = PDFEncoding::convertTextString(info.name); info.colorSpaceIndex = uint32_t(i); info.colorSpace = colorSpacePointer; info.spotColorIndex = uint32_t(m_spotColors.size()); @@ -1521,15 +1660,13 @@ void PDFInkMapper::createSpotColors(bool activate) } } - if (activate) + size_t minIndex = qMin(uint32_t(m_spotColors.size()), MAX_SPOT_COLOR_COMPONENTS); + for (size_t i = 0; i < minIndex; ++i) { - size_t minIndex = qMin(uint32_t(m_spotColors.size()), MAX_SPOT_COLOR_COMPONENTS); - for (size_t i = 0; i < minIndex; ++i) - { - m_spotColors[i].active = true; - } - m_activeSpotColors = minIndex; + m_spotColors[i].canBeActive = true; } + + setSpotColorsActive(activate); } bool PDFInkMapper::containsSpotColor(const QByteArray& colorName) const @@ -1537,7 +1674,7 @@ bool PDFInkMapper::containsSpotColor(const QByteArray& colorName) const return getSpotColor(colorName) != nullptr; } -const PDFInkMapper::SpotColorInfo* PDFInkMapper::getSpotColor(const QByteArray& colorName) const +const PDFInkMapper::ColorInfo* PDFInkMapper::getSpotColor(const QByteArray& colorName) const { auto it = std::find_if(m_spotColors.cbegin(), m_spotColors.cend(), [&colorName](const auto& info) { return info.name == colorName; }); if (it != m_spotColors.cend()) @@ -1548,6 +1685,30 @@ const PDFInkMapper::SpotColorInfo* PDFInkMapper::getSpotColor(const QByteArray& return nullptr; } +void PDFInkMapper::setSpotColorsActive(bool active) +{ + m_activeSpotColors = 0; + + if (active) + { + for (auto& spotColor : m_spotColors) + { + if (spotColor.canBeActive) + { + spotColor.active = true; + ++m_activeSpotColors; + } + } + } + else + { + for (auto& spotColor : m_spotColors) + { + spotColor.active = false; + } + } +} + PDFInkMapping PDFInkMapper::createMapping(const PDFAbstractColorSpace* sourceColorSpace, const PDFAbstractColorSpace* targetColorSpace, PDFPixelFormat targetPixelFormat) const @@ -1590,7 +1751,7 @@ PDFInkMapping PDFInkMapper::createMapping(const PDFAbstractColorSpace* sourceCol else if (!separationColorSpace->isNone() && !separationColorSpace->getColorName().isEmpty()) { const QByteArray& colorName = separationColorSpace->getColorName(); - const SpotColorInfo* info = getSpotColor(colorName); + const ColorInfo* info = getSpotColor(colorName); if (info && info->active && targetPixelFormat.hasSpotColors() && info->spotColorIndex < targetPixelFormat.getSpotColorChannelCount()) { mapping.map(0, uint8_t(targetPixelFormat.getSpotColorChannelIndexStart() + info->spotColorIndex)); @@ -1610,7 +1771,7 @@ PDFInkMapping PDFInkMapper::createMapping(const PDFAbstractColorSpace* sourceCol for (size_t i = 0; i < colorants.size(); ++i) { const PDFDeviceNColorSpace::ColorantInfo& colorantInfo = colorants[i]; - const SpotColorInfo* info = getSpotColor(colorantInfo.name); + const ColorInfo* info = getSpotColor(colorantInfo.name); if (info && info->active && targetPixelFormat.hasSpotColors() && info->spotColorIndex < targetPixelFormat.getSpotColorChannelCount()) { diff --git a/Pdf4QtLib/sources/pdftransparencyrenderer.h b/Pdf4QtLib/sources/pdftransparencyrenderer.h index 93427d7..5d467f8 100644 --- a/Pdf4QtLib/sources/pdftransparencyrenderer.h +++ b/Pdf4QtLib/sources/pdftransparencyrenderer.h @@ -97,6 +97,8 @@ public: static constexpr PDFPixelFormat removeSpotColors(PDFPixelFormat format) { return PDFPixelFormat(format.getProcessColorChannelCount(), 0, format.getFlags()); } static constexpr PDFPixelFormat removeShapeAndOpacity(PDFPixelFormat format) { return PDFPixelFormat(format.getProcessColorChannelCount(), format.getSpotColorChannelCount(), format.hasProcessColorsSubtractive() ? FLAG_PROCESS_COLORS_SUBTRACTIVE : 0); } + static constexpr uint32_t getAllColorsMask() { return 0xFFFF; } + static constexpr PDFPixelFormat createFormat(uint8_t processColors, uint8_t spotColors, bool withShapeAndOpacity, bool processColorSubtractive) { return PDFPixelFormat(processColors, spotColors, (withShapeAndOpacity ? FLAG_HAS_SHAPE_CHANNEL + FLAG_HAS_OPACITY_CHANNEL : 0) + (processColorSubtractive ? FLAG_PROCESS_COLORS_SUBTRACTIVE : 0)); @@ -277,19 +279,28 @@ class Pdf4QtLIBSHARED_EXPORT PDFInkMapper public: explicit PDFInkMapper(const PDFDocument* document); - struct SpotColorInfo + struct ColorInfo { QByteArray name; + QString textName; uint32_t spotColorIndex = 0; ///< Index of this spot color uint32_t colorSpaceIndex = 0; ///< Index into DeviceN color space (index of colorant) PDFColorSpacePointer colorSpace; + bool canBeActive = false; ///< Can spot color be activated? bool active = false; ///< Is spot color active? + bool isSpot = true; }; static constexpr const uint32_t MAX_COLOR_COMPONENTS = PDF_MAX_COLOR_COMPONENTS; static constexpr const uint32_t MAX_DEVICE_COLOR_COMPONENTS = 4; static constexpr const uint32_t MAX_SPOT_COLOR_COMPONENTS = MAX_COLOR_COMPONENTS - MAX_DEVICE_COLOR_COMPONENTS - 2; + /// Returns a vector of separations correspoding to the process colors + /// and spot colors. Only active spot colors are added. Only 1, 3 and 4 + /// process colors are supported. + /// \param processColorCount Process color count + std::vector getSeparations(uint32_t processColorCount) const; + /// Scan document for spot colors and fills color info /// \param activate Set spot colors active? void createSpotColors(bool activate); @@ -303,7 +314,11 @@ public: /// Returns spot color information (or nullptr, if spot color is not present) /// \param colorName Color name - const SpotColorInfo* getSpotColor(const QByteArray& colorName) const; + const ColorInfo* getSpotColor(const QByteArray& colorName) const; + + /// Activates / deactivates spot colors + /// \param active Make spot colors active? + void setSpotColorsActive(bool active); /// Creates color mapping from source color space to the target color space. /// If mapping cannot be created, then invalid mapping is returned. Target @@ -318,7 +333,7 @@ public: private: const PDFDocument* m_document; - std::vector m_spotColors; + std::vector m_spotColors; size_t m_activeSpotColors = 0; }; @@ -456,13 +471,23 @@ struct PDFTransparencyRendererSettings /// Use multithreading when painter paths are painted? /// Multithreading is used to - MultithreadedPathSampler = 0x0002 + MultithreadedPathSampler = 0x0002, + + /// When using CMYK process color space, transfer spot + /// colors to the CMYK color space. + SeparationSimulation = 0x0004, + + /// Use active color mask + ActiveColorMask = 0x0008 }; Q_DECLARE_FLAGS(Flags, Flag) /// Flags Flags flags = None; + + /// Active color mask + uint32_t activeColorMask = PDFPixelFormat::getAllColorsMask(); }; /// Renders PDF pages with transparency, using 32-bit floating point precision. @@ -550,6 +575,8 @@ private: PDFFloatBitmapWithColorSpace immediateBackdrop; ///< Immediate backdrop PDFFloatBitmap softMask; ///< Soft mask for this group PDFColorSpacePointer blendColorSpace; + bool filterColorsUsingMask = false; + uint32_t activeColorMask = PDFPixelFormat::getAllColorsMask(); }; struct PDFTransparencyPainterState diff --git a/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.cpp b/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.cpp index 897004d..2b9bcb1 100644 --- a/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.cpp +++ b/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.cpp @@ -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::of(&QDoubleSpinBox::valueChanged), this, &OutputPreviewDialog::onPaperColorChanged); + connect(ui->greenPaperColorEdit, QOverload::of(&QDoubleSpinBox::valueChanged), this, &OutputPreviewDialog::onPaperColorChanged); + connect(ui->bluePaperColorEdit, QOverload::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 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& 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 diff --git a/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.h b/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.h index 8d3cd5d..1ac1067 100644 --- a/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.h +++ b/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.h @@ -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& 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; diff --git a/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.ui b/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.ui index e55be25..6acd91e 100644 --- a/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.ui +++ b/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.ui @@ -64,6 +64,85 @@ Settings + + + + + Red + + + + + + + Blue + + + + + + + Green + + + + + + + Simulate separations + + + true + + + + + + + Simulate paper color + + + + + + + 1.000000000000000 + + + 0.100000000000000 + + + 1.000000000000000 + + + + + + + 1.000000000000000 + + + 0.100000000000000 + + + 1.000000000000000 + + + + + + + 1.000000000000000 + + + 0.100000000000000 + + + 1.000000000000000 + + + + @@ -73,7 +152,16 @@ - + + + false + + + + 1 + + +