diff --git a/Pdf4QtLib/sources/pdftransparencyrenderer.cpp b/Pdf4QtLib/sources/pdftransparencyrenderer.cpp index 4c1dce8..6334d99 100644 --- a/Pdf4QtLib/sources/pdftransparencyrenderer.cpp +++ b/Pdf4QtLib/sources/pdftransparencyrenderer.cpp @@ -989,12 +989,13 @@ void PDFTransparencyRenderer::beginPaint(QSize pixelSize) Q_ASSERT(m_deviceColorSpace); Q_ASSERT(m_processColorSpace); + m_originalProcessBitmap = PDFFloatBitmapWithColorSpace(); m_transparencyGroupDataStack.clear(); m_painterStateStack.push(PDFTransparencyPainterState()); // Initialize initial opaque soft mask - PDFFloatBitmap initialSoftMaskBitmap(pixelSize.width(), pixelSize.height(), PDFPixelFormat::createOpacityMask()); - initialSoftMaskBitmap.makeOpaque(); + PDFFloatBitmap initialSoftMaskBitmap; + createOpaqueSoftMask(initialSoftMaskBitmap, pixelSize.width(), pixelSize.height()); m_painterStateStack.top().softMask = PDFTransparencySoftMask(true, qMove(initialSoftMaskBitmap)); PDFPixelFormat pixelFormat = PDFPixelFormat::createFormat(uint8_t(m_deviceColorSpace->getColorComponentCount()), @@ -1033,6 +1034,7 @@ void PDFTransparencyRenderer::beginPaint(QSize pixelSize) m_settings.activeColorMask != PDFPixelFormat::getAllColorsMask()); m_transparencyGroupDataStack.back().activeColorMask = m_settings.activeColorMask; m_transparencyGroupDataStack.back().transformSpotsToDevice = m_settings.flags.testFlag(PDFTransparencyRendererSettings::SeparationSimulation); + m_transparencyGroupDataStack.back().saveOriginalImage = m_settings.flags.testFlag(PDFTransparencyRendererSettings::SaveOriginalProcessImage); } const PDFFloatBitmap& PDFTransparencyRenderer::endPaint() @@ -2524,6 +2526,11 @@ void PDFTransparencyRenderer::performEndTransparencyGroup(ProcessOrder order, co } } + if (sourceData.saveOriginalImage) + { + m_originalProcessBitmap = sourceData.immediateBackdrop; + } + // Collapse spot colors if (sourceData.transformSpotsToDevice) { diff --git a/Pdf4QtLib/sources/pdftransparencyrenderer.h b/Pdf4QtLib/sources/pdftransparencyrenderer.h index 3bca7b9..533ea9a 100644 --- a/Pdf4QtLib/sources/pdftransparencyrenderer.h +++ b/Pdf4QtLib/sources/pdftransparencyrenderer.h @@ -136,7 +136,7 @@ private: /// Represents float bitmap with arbitrary color channel count. Bitmap can also /// have auxiliary channels, such as shape and opacity channels. -class PDFFloatBitmap +class Pdf4QtLIBSHARED_EXPORT PDFFloatBitmap { public: explicit PDFFloatBitmap(); @@ -311,7 +311,7 @@ private: }; /// Float bitmap with color space -class PDFFloatBitmapWithColorSpace : public PDFFloatBitmap +class Pdf4QtLIBSHARED_EXPORT PDFFloatBitmapWithColorSpace : public PDFFloatBitmap { public: explicit PDFFloatBitmapWithColorSpace(); @@ -602,6 +602,11 @@ struct PDFTransparencyRendererSettings /// Display tiling patterns (if this flag is false, tiling patterns aren't processed) DisplayTilingPatterns = 0x0200, + + /// Saves process image before it is transformed into device space + /// and before separation simulation is applied. Active color mask + /// is still applied to this image. + SaveOriginalProcessImage = 0x0400, }; Q_DECLARE_FLAGS(Flags, Flag) @@ -671,6 +676,11 @@ public: /// \param color Color void clearColor(const PDFColor& color); + /// Returns original process bitmap, before it is transformed into device space, + /// and before separation simulation is being processed. Active color mask is still + /// applied to this image. + PDFFloatBitmapWithColorSpace getOriginalProcessBitmap() const { return m_originalProcessBitmap; } + virtual bool isContentKindSuppressed(ContentKind kind) const override; virtual void performPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule) override; virtual bool performPathPaintingUsingShading(const QPainterPath& path, bool stroke, bool fill, const PDFShadingPattern* shadingPattern) override; @@ -742,6 +752,7 @@ private: bool filterColorsUsingMask = false; uint32_t activeColorMask = PDFPixelFormat::getAllColorsMask(); bool transformSpotsToDevice = false; + bool saveOriginalImage = false; }; struct PDFTransparencyPainterState @@ -901,6 +912,7 @@ private: PDFCachedItem m_mappedFillColor; PDFTransparencyRendererSettings m_settings; PDFDrawBuffer m_drawBuffer; + PDFFloatBitmapWithColorSpace m_originalProcessBitmap; }; } // namespace pdf diff --git a/Pdf4QtLib/sources/pdfwidgetutils.cpp b/Pdf4QtLib/sources/pdfwidgetutils.cpp index 23ffe86..ff4cd41 100644 --- a/Pdf4QtLib/sources/pdfwidgetutils.cpp +++ b/Pdf4QtLib/sources/pdfwidgetutils.cpp @@ -28,7 +28,7 @@ int qt_default_dpi_y() { return 96; } namespace pdf { -int PDFWidgetUtils::getPixelSize(QPaintDevice* device, pdf::PDFReal sizeMM) +int PDFWidgetUtils::getPixelSize(const QPaintDevice* device, pdf::PDFReal sizeMM) { const int width = device->width(); const int height = device->height(); @@ -43,21 +43,21 @@ int PDFWidgetUtils::getPixelSize(QPaintDevice* device, pdf::PDFReal sizeMM) } } -int PDFWidgetUtils::scaleDPI_x(QPaintDevice* device, int unscaledSize) +int PDFWidgetUtils::scaleDPI_x(const QPaintDevice* device, int unscaledSize) { const double logicalDPI_x = device->logicalDpiX(); const double defaultDPI_x = qt_default_dpi_x(); return (logicalDPI_x / defaultDPI_x) * unscaledSize; } -int PDFWidgetUtils::scaleDPI_y(QPaintDevice* device, int unscaledSize) +int PDFWidgetUtils::scaleDPI_y(const QPaintDevice* device, int unscaledSize) { const double logicalDPI_y = device->logicalDpiY(); const double defaultDPI_y = qt_default_dpi_y(); return (logicalDPI_y / defaultDPI_y) * unscaledSize; } -PDFReal PDFWidgetUtils::scaleDPI_x(QPaintDevice* device, PDFReal unscaledSize) +PDFReal PDFWidgetUtils::scaleDPI_x(const QPaintDevice* device, PDFReal unscaledSize) { const double logicalDPI_x = device->logicalDpiX(); const double defaultDPI_x = qt_default_dpi_x(); @@ -77,7 +77,7 @@ void PDFWidgetUtils::scaleWidget(QWidget* widget, QSize unscaledSize) widget->resize(width, height); } -QSize PDFWidgetUtils::scaleDPI(QPaintDevice* widget, QSize unscaledSize) +QSize PDFWidgetUtils::scaleDPI(const QPaintDevice* widget, QSize unscaledSize) { const double logicalDPI_x = widget->logicalDpiX(); const double logicalDPI_y = widget->logicalDpiY(); diff --git a/Pdf4QtLib/sources/pdfwidgetutils.h b/Pdf4QtLib/sources/pdfwidgetutils.h index fb0b93a..51332dd 100644 --- a/Pdf4QtLib/sources/pdfwidgetutils.h +++ b/Pdf4QtLib/sources/pdfwidgetutils.h @@ -31,19 +31,19 @@ public: PDFWidgetUtils() = delete; /// Converts size in MM to pixel size - static int getPixelSize(QPaintDevice* device, pdf::PDFReal sizeMM); + static int getPixelSize(const QPaintDevice* device, pdf::PDFReal sizeMM); /// Scale horizontal DPI value /// \param device Paint device to obtain logical DPI for scaling - static int scaleDPI_x(QPaintDevice* device, int unscaledSize); + static int scaleDPI_x(const QPaintDevice* device, int unscaledSize); /// Scale vertical DPI value /// \param device Paint device to obtain logical DPI for scaling - static int scaleDPI_y(QPaintDevice* device, int unscaledSize); + static int scaleDPI_y(const QPaintDevice* device, int unscaledSize); /// Scale horizontal DPI value /// \param device Paint device to obtain logical DPI for scaling - static PDFReal scaleDPI_x(QPaintDevice* device, PDFReal unscaledSize); + static PDFReal scaleDPI_x(const QPaintDevice* device, PDFReal unscaledSize); /// Scales widget based on DPI /// \param widget Widget to be scaled @@ -53,7 +53,7 @@ public: /// Scales size based on DPI /// \param device Paint device to obtain logical DPI for scaling /// \param unscaledSize Unscaled size - static QSize scaleDPI(QPaintDevice* widget, QSize unscaledSize); + static QSize scaleDPI(const QPaintDevice* widget, QSize unscaledSize); }; } // namespace pdf diff --git a/Pdf4QtViewerPlugins/OutputPreviewPlugin/OutputPreviewPlugin.pro b/Pdf4QtViewerPlugins/OutputPreviewPlugin/OutputPreviewPlugin.pro index b531d2f..887a884 100644 --- a/Pdf4QtViewerPlugins/OutputPreviewPlugin/OutputPreviewPlugin.pro +++ b/Pdf4QtViewerPlugins/OutputPreviewPlugin/OutputPreviewPlugin.pro @@ -34,11 +34,13 @@ CONFIG += c++11 SOURCES += \ outputpreviewdialog.cpp \ - outputpreviewplugin.cpp + outputpreviewplugin.cpp \ + outputpreviewwidget.cpp HEADERS += \ outputpreviewdialog.h \ - outputpreviewplugin.h + outputpreviewplugin.h \ + outputpreviewwidget.h CONFIG += force_debug_info diff --git a/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.cpp b/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.cpp index d77cec1..72a82c4 100644 --- a/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.cpp +++ b/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.cpp @@ -44,12 +44,14 @@ OutputPreviewDialog::OutputPreviewDialog(const pdf::PDFDocument* document, pdf:: ui->pageIndexScrollBar->setValue(1); ui->pageIndexScrollBar->setMaximum(int(document->getCatalog()->getPageCount())); - ui->displayModeComboBox->addItem(tr("Separations"), Separations); - ui->displayModeComboBox->addItem(tr("Color Warnings | Ink Coverage"), ColorWarningInkCoverage); - ui->displayModeComboBox->addItem(tr("Color Warnings | Rich Black"), ColorWarningRichBlack); - ui->displayModeComboBox->addItem(tr("Ink Coverage"), InkCoverage); + ui->displayModeComboBox->addItem(tr("Separations"), OutputPreviewWidget::Separations); + ui->displayModeComboBox->addItem(tr("Color Warnings | Ink Coverage"), OutputPreviewWidget::ColorWarningInkCoverage); + ui->displayModeComboBox->addItem(tr("Color Warnings | Rich Black"), OutputPreviewWidget::ColorWarningRichBlack); + ui->displayModeComboBox->addItem(tr("Ink Coverage"), OutputPreviewWidget::InkCoverage); ui->displayModeComboBox->setCurrentIndex(0); + ui->imageWidget->setInkMapper(&m_inkMapper); + m_inkMapper.createSpotColors(ui->simulateSeparationsCheckBox->isChecked()); connect(ui->simulateSeparationsCheckBox, &QCheckBox::clicked, this, &OutputPreviewDialog::onSimulateSeparationsChecked); connect(ui->simulatePaperColorCheckBox, &QCheckBox::clicked, this, &OutputPreviewDialog::onSimulatePaperColorChecked); @@ -208,7 +210,7 @@ void OutputPreviewDialog::updatePageImage() const pdf::PDFPage* page = m_document->getCatalog()->getPage(ui->pageIndexScrollBar->value() - 1); if (!page) { - ui->imageLabel->setPixmap(QPixmap()); + ui->imageWidget->clear(); return; } @@ -255,9 +257,10 @@ void OutputPreviewDialog::updatePageImage() flags.setFlag(pdf::PDFTransparencyRendererSettings::DisplayVectorGraphics, ui->displayVectorGraphicsCheckBox->isChecked()); flags.setFlag(pdf::PDFTransparencyRendererSettings::DisplayShadings, ui->displayShadingCheckBox->isChecked()); flags.setFlag(pdf::PDFTransparencyRendererSettings::DisplayTilingPatterns, ui->displayTilingPatternsCheckBox->isChecked()); + flags.setFlag(pdf::PDFTransparencyRendererSettings::SaveOriginalProcessImage, true); m_inkMapperForRendering = m_inkMapper; - QSize renderSize = ui->imageLabel->size(); + QSize renderSize = ui->imageWidget->getPageImageSizeHint(); auto renderImage = [this, page, renderSize, paperColor, activeColorMask, flags]() -> RenderedImage { return renderPage(page, renderSize, paperColor, activeColorMask, flags); @@ -312,6 +315,8 @@ OutputPreviewDialog::RenderedImage OutputPreviewDialog::renderPage(const pdf::PD QImage image = renderer.toImage(false, true, paperColor); result.image = qMove(image); + result.originalProcessImage = renderer.getOriginalProcessBitmap(); + result.pageSize = page->getRotatedMediaBoxMM().size(); return result; } @@ -326,7 +331,7 @@ void OutputPreviewDialog::onPageImageRendered() m_futureWatcher->deleteLater(); m_futureWatcher = nullptr; - ui->imageLabel->setPixmap(QPixmap::fromImage(result.image)); + ui->imageWidget->setPageImage(qMove(result.image), qMove(result.originalProcessImage), result.pageSize); if (m_needUpdateImage) { diff --git a/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.h b/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.h index 16110c8..3cbcad0 100644 --- a/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.h +++ b/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.h @@ -21,6 +21,7 @@ #include "pdfdocument.h" #include "pdfdrawwidget.h" #include "pdftransparencyrenderer.h" +#include "outputpreviewwidget.h" #include #include @@ -50,15 +51,6 @@ public: virtual void reject() override; private: - - enum DisplayMode - { - Separations, - ColorWarningInkCoverage, - ColorWarningRichBlack, - InkCoverage - }; - void updateInks(); void updatePaperColorWidgets(); @@ -70,6 +62,8 @@ private: struct RenderedImage { QImage image; + pdf::PDFFloatBitmapWithColorSpace originalProcessImage; + QSizeF pageSize; QList errors; }; diff --git a/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.ui b/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.ui index 66a345f..39021fa 100644 --- a/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.ui +++ b/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewdialog.ui @@ -41,11 +41,7 @@ 0 - - - - - + @@ -320,6 +316,14 @@ + + + pdfplugin::OutputPreviewWidget + QWidget +
outputpreviewwidget.h
+ 1 +
+
diff --git a/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewwidget.cpp b/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewwidget.cpp new file mode 100644 index 0000000..0a311a8 --- /dev/null +++ b/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewwidget.cpp @@ -0,0 +1,312 @@ +// Copyright (C) 2021 Jakub Melka +// +// This file is part of Pdf4Qt. +// +// Pdf4Qt is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Pdf4Qt is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with Pdf4Qt. If not, see . + +#include "outputpreviewwidget.h" + +#include "pdfwidgetutils.h" + +#include +#include + +namespace pdfplugin +{ + +OutputPreviewWidget::OutputPreviewWidget(QWidget* parent) : + BaseClass(parent), + m_inkMapper(nullptr), + m_displayMode(Separations) +{ + +} + +QSize OutputPreviewWidget::sizeHint() const +{ + return pdf::PDFWidgetUtils::scaleDPI(this, QSize(400, 300)); +} + +QSize OutputPreviewWidget::minimumSizeHint() const +{ + return pdf::PDFWidgetUtils::scaleDPI(this, QSize(200, 200)); +} + +void OutputPreviewWidget::clear() +{ + m_pageImage = QImage(); + m_originalProcessBitmap = pdf::PDFFloatBitmapWithColorSpace(); + m_pageSizeMM = QSizeF(); + m_infoBoxItems.clear(); + update(); +} + +void OutputPreviewWidget::setPageImage(QImage image, pdf::PDFFloatBitmapWithColorSpace originalProcessBitmap, QSizeF pageSizeMM) +{ + m_pageImage = qMove(image); + m_originalProcessBitmap = qMove(originalProcessBitmap); + m_pageSizeMM = pageSizeMM; + buildInfoBoxItems(); + update(); +} + +void OutputPreviewWidget::paintEvent(QPaintEvent* event) +{ + QPainter painter(this); + + Q_UNUSED(event); + + QRect rect = this->rect(); + painter.fillRect(rect, Qt::gray); + + QRect contentRect = getContentRect(); + QRect pageImageRect = getPageImageRect(contentRect); + + if (pageImageRect.isValid() && !m_pageImage.isNull()) + { + painter.save(); + painter.setClipRect(pageImageRect, Qt::IntersectClip); + painter.translate(0, (pageImageRect.height() - m_pageImage.height()) / 2); + painter.drawImage(pageImageRect.topLeft(), m_pageImage); + painter.restore(); + } + + if (!m_infoBoxItems.empty()) + { + painter.save(); + + int infoBoxWidth = getInfoBoxWidth(); + int itemHorizontalMargin = getInfoBoxContentHorizontalMargin(); + + QRect infoBoxRect = contentRect; + infoBoxRect.setLeft(infoBoxRect.right() - infoBoxWidth); + + painter.setPen(Qt::black); + painter.setBrush(QBrush(Qt::white)); + painter.drawRect(infoBoxRect); + painter.setClipRect(infoBoxRect, Qt::IntersectClip); + painter.setBrush(Qt::NoBrush); + + QFontMetrics fontMetrics(painter.font(), painter.device()); + QRect rowRect = infoBoxRect; + rowRect.setHeight(fontMetrics.lineSpacing()); + + for (const auto& infoBoxItem : m_infoBoxItems) + { + switch (infoBoxItem.style) + { + case pdfplugin::OutputPreviewWidget::Header: + { + painter.save(); + + QFont font = painter.font(); + font.setBold(true); + painter.setFont(font); + + painter.drawText(rowRect, Qt::AlignCenter | Qt::TextSingleLine, infoBoxItem.caption); + + painter.restore(); + break; + } + + case pdfplugin::OutputPreviewWidget::Separator: + break; + + case pdfplugin::OutputPreviewWidget::ColoredItem: + { + QRect cellRect = rowRect.marginsRemoved(QMargins(itemHorizontalMargin, 0, itemHorizontalMargin, 0)); + + if (infoBoxItem.color.isValid()) + { + QRect ellipseRect = cellRect; + ellipseRect.setWidth(ellipseRect.height()); + cellRect.setLeft(ellipseRect.right() + 1); + + painter.save(); + painter.setPen(Qt::NoPen); + painter.setBrush(QBrush(infoBoxItem.color)); + painter.drawEllipse(ellipseRect); + painter.restore(); + } + + painter.drawText(cellRect, Qt::AlignVCenter | Qt::AlignLeft | Qt::TextSingleLine, infoBoxItem.caption); + painter.drawText(cellRect, Qt::AlignVCenter | Qt::AlignRight | Qt::TextSingleLine, infoBoxItem.value); + break; + } + + default: + Q_ASSERT(false); + break; + } + + rowRect.translate(0, rowRect.height()); + } + + painter.restore(); + } +} + +QMargins OutputPreviewWidget::getDrawMargins() const +{ + const int horizontalMargin = pdf::PDFWidgetUtils::scaleDPI_x(this, 5); + const int verticalMargin = pdf::PDFWidgetUtils::scaleDPI_y(this, 5); + + return QMargins(horizontalMargin, verticalMargin, horizontalMargin, verticalMargin); +} + +QRect OutputPreviewWidget::getContentRect() const +{ + QRect rect = this->rect(); + QRect contentRect = rect.marginsRemoved(getDrawMargins()); + return contentRect; +} + +QRect OutputPreviewWidget::getPageImageRect(QRect contentRect) const +{ + int infoBoxWidth = getInfoBoxWidth(); + + if (infoBoxWidth > 0) + { + infoBoxWidth += pdf::PDFWidgetUtils::scaleDPI_x(this, 5); + } + + contentRect.setRight(contentRect.right() - infoBoxWidth); + return contentRect; +} + +int OutputPreviewWidget::getInfoBoxWidth() const +{ + if (m_infoBoxItems.empty()) + { + return 0; + } + + return pdf::PDFWidgetUtils::scaleDPI_x(this, 150); +} + +int OutputPreviewWidget::getInfoBoxContentHorizontalMargin() const +{ + return pdf::PDFWidgetUtils::scaleDPI_x(this, 5); +} + +void OutputPreviewWidget::buildInfoBoxItems() +{ + m_infoBoxItems.clear(); + + switch (m_displayMode) + { + case pdfplugin::OutputPreviewWidget::Separations: + case pdfplugin::OutputPreviewWidget::ColorWarningInkCoverage: + case pdfplugin::OutputPreviewWidget::ColorWarningRichBlack: + { + if (m_originalProcessBitmap.getWidth() > 0 && m_originalProcessBitmap.getHeight() > 0) + { + const pdf::PDFPixelFormat pixelFormat = m_originalProcessBitmap.getPixelFormat(); + std::vector separations = m_inkMapper->getSeparations(pixelFormat.getProcessColorChannelCount(), true); + + // Count process/spot inks + + int processInks = 0; + int spotInks = 0; + + for (const auto& colorInfo : separations) + { + if (!colorInfo.isSpot) + { + ++processInks; + } + else + { + ++spotInks; + } + } + + if (processInks > 0) + { + addInfoBoxSeparator(); + addInfoBoxHeader(tr("Process Inks")); + + for (const auto& colorInfo : separations) + { + if (colorInfo.isSpot) + { + continue; + } + + addInfoBoxColoredItem(Qt::green, colorInfo.textName, QString("100 %")); + } + } + + if (spotInks > 0) + { + addInfoBoxSeparator(); + addInfoBoxHeader(tr("Spot Inks")); + + for (const auto& colorInfo : separations) + { + if (!colorInfo.isSpot) + { + continue; + } + + addInfoBoxColoredItem(Qt::blue, colorInfo.textName, QString("100 %")); + } + } + } + break; + } + + case pdfplugin::OutputPreviewWidget::InkCoverage: + break; + + default: + Q_ASSERT(false); + break; + } +} + +void OutputPreviewWidget::addInfoBoxHeader(QString caption) +{ + m_infoBoxItems.push_back(InfoBoxItem(Header, QColor(), caption, QString())); +} + +void OutputPreviewWidget::addInfoBoxSeparator() +{ + if (!m_infoBoxItems.empty()) + { + m_infoBoxItems.push_back(InfoBoxItem(Separator, QColor(), QString(), QString())); + } +} + +void OutputPreviewWidget::addInfoBoxColoredItem(QColor color, QString caption, QString value) +{ + m_infoBoxItems.push_back(InfoBoxItem(ColoredItem, color, caption, value)); +} + +const pdf::PDFInkMapper* OutputPreviewWidget::getInkMapper() const +{ + return m_inkMapper; +} + +void OutputPreviewWidget::setInkMapper(const pdf::PDFInkMapper* inkMapper) +{ + m_inkMapper = inkMapper; +} + +QSize OutputPreviewWidget::getPageImageSizeHint() const +{ + return getPageImageRect(getContentRect()).size(); +} + +} // pdfplugin diff --git a/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewwidget.h b/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewwidget.h new file mode 100644 index 0000000..5a67499 --- /dev/null +++ b/Pdf4QtViewerPlugins/OutputPreviewPlugin/outputpreviewwidget.h @@ -0,0 +1,112 @@ +// Copyright (C) 2021 Jakub Melka +// +// This file is part of Pdf4Qt. +// +// Pdf4Qt is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Pdf4Qt is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with Pdf4Qt. If not, see . + +#ifndef OUTPUTPREVIEWWIDGET_H +#define OUTPUTPREVIEWWIDGET_H + +#include "pdftransparencyrenderer.h" + +#include + +namespace pdfplugin +{ + +class OutputPreviewWidget : public QWidget +{ + Q_OBJECT + +private: + using BaseClass = QWidget; + +public: + explicit OutputPreviewWidget(QWidget* parent); + + enum DisplayMode + { + Separations, + ColorWarningInkCoverage, + ColorWarningRichBlack, + InkCoverage + }; + + virtual QSize sizeHint() const override; + virtual QSize minimumSizeHint() const override; + + /// Clears all widget contents + void clear(); + + /// Set active image + void setPageImage(QImage image, pdf::PDFFloatBitmapWithColorSpace originalProcessBitmap, QSizeF pageSizeMM); + + const pdf::PDFInkMapper* getInkMapper() const; + void setInkMapper(const pdf::PDFInkMapper* inkMapper); + + /// Returns page image size hint (ideal size of page image) + QSize getPageImageSizeHint() const; + +protected: + virtual void paintEvent(QPaintEvent* event) override; + +private: + QMargins getDrawMargins() const; + QRect getContentRect() const; + QRect getPageImageRect(QRect contentRect) const; + + int getInfoBoxWidth() const; + int getInfoBoxContentHorizontalMargin() const; + void buildInfoBoxItems(); + + void addInfoBoxHeader(QString caption); + void addInfoBoxSeparator(); + void addInfoBoxColoredItem(QColor color, QString caption, QString value); + + enum InfoBoxStyle + { + Header, + Separator, + ColoredItem + }; + + struct InfoBoxItem + { + InfoBoxItem(InfoBoxStyle style, QColor color, QString caption, QString value) : + style(style), + color(color), + caption(caption), + value(value) + { + + } + + InfoBoxStyle style = InfoBoxStyle::Separator; + QColor color; + QString caption; + QString value; + }; + + const pdf::PDFInkMapper* m_inkMapper; + DisplayMode m_displayMode; + std::vector m_infoBoxItems; + + QImage m_pageImage; + pdf::PDFFloatBitmapWithColorSpace m_originalProcessBitmap; + QSizeF m_pageSizeMM; +}; + +} // pdfplugin + +#endif // OUTPUTPREVIEWWIDGET_H