Some bugfixing

This commit is contained in:
Jakub Melka 2021-01-31 19:15:11 +01:00
parent 8d6b47dbd4
commit 3a2fa64ac0
7 changed files with 123 additions and 13 deletions

View File

@ -697,6 +697,7 @@ bool PDFAbstractColorSpace::transform(const PDFAbstractColorSpace* source,
std::vector<PDFColorComponent> transformedOutputColorsVector;
PDFColorBuffer transformedInput = input;
PDFColorBuffer transformedOutput = output;
params.intent = intent;
switch (source->getColorSpace())
{

View File

@ -534,11 +534,14 @@ PDFTransparencyRenderer::PDFTransparencyRenderer(const PDFPage* page,
const PDFFontCache* fontCache,
const PDFCMS* cms,
const PDFOptionalContentActivity* optionalContentActivity,
const PDFInkMapper* inkMapper,
QMatrix pagePointToDevicePointMatrix) :
BaseClass(page, document, fontCache, cms, optionalContentActivity, pagePointToDevicePointMatrix, PDFMeshQualitySettings()),
m_inkMapper(inkMapper),
m_active(false)
{
m_deviceColorSpace.reset(new PDFDeviceRGBColorSpace());
m_processColorSpace.reset(new PDFDeviceCMYKColorSpace());
}
void PDFTransparencyRenderer::setDeviceColorSpace(PDFColorSpacePointer colorSpace)
@ -550,16 +553,51 @@ void PDFTransparencyRenderer::setDeviceColorSpace(PDFColorSpacePointer colorSpac
}
}
void PDFTransparencyRenderer::beginPaint()
void PDFTransparencyRenderer::setProcessColorSpace(PDFColorSpacePointer colorSpace)
{
if (!colorSpace || colorSpace->isBlendColorSpace())
{
// Set process color space only, when it is a blend color space
m_processColorSpace = colorSpace;
}
}
void PDFTransparencyRenderer::beginPaint(QSize pixelSize)
{
Q_ASSERT(!m_active);
m_active = true;
Q_ASSERT(pixelSize.isValid());
Q_ASSERT(m_deviceColorSpace);
Q_ASSERT(m_processColorSpace);
PDFPixelFormat pixelFormat = PDFPixelFormat::createFormat(uint8_t(m_deviceColorSpace->getColorComponentCount()),
uint8_t(m_inkMapper->getActiveSpotColorCount()),
true, m_deviceColorSpace->getColorComponentCount() == 4);
PDFTransparencyGroupPainterData deviceGroup;
deviceGroup.alphaIsShape = getGraphicState()->getAlphaIsShape();
deviceGroup.alphaStroke = getGraphicState()->getAlphaStroking();
deviceGroup.alphaFill = getGraphicState()->getAlphaFilling();
deviceGroup.blendMode = getGraphicState()->getBlendMode();
deviceGroup.blackPointCompensationMode = getGraphicState()->getBlackPointCompensationMode();
deviceGroup.renderingIntent = RenderingIntent::RelativeColorimetric;
deviceGroup.initialBackdrop = PDFFloatBitmapWithColorSpace(pixelSize.width(), pixelSize.height(), pixelFormat, m_deviceColorSpace);
deviceGroup.immediateBackdrop = deviceGroup.initialBackdrop;
deviceGroup.blendColorSpace = m_deviceColorSpace;
m_transparencyGroupDataStack.emplace_back(qMove(deviceGroup));
// Create page transparency group
PDFObject pageTransparencyGroupObject = getPage()->getTransparencyGroup(&getDocument()->getStorage());
PDFTransparencyGroup transparencyGroup = parseTransparencyGroup(pageTransparencyGroupObject);
transparencyGroup.isolated = true;
if (!transparencyGroup.colorSpacePointer)
{
transparencyGroup.colorSpacePointer = m_processColorSpace;
}
m_pageTransparencyGroupGuard.reset(new PDFTransparencyGroupGuard(this, qMove(transparencyGroup)));
}
@ -779,7 +817,16 @@ void PDFInkMapper::createSpotColors(bool activate)
std::size_t colorSpaces = colorSpaceDictionary->getCount();
for (size_t csIndex = 0; csIndex < colorSpaces; ++ csIndex)
{
PDFColorSpacePointer colorSpacePointer = PDFAbstractColorSpace::createColorSpace(colorSpaceDictionary, m_document, colorSpaceDictionary->getValue(csIndex));
PDFColorSpacePointer colorSpacePointer;
try
{
colorSpacePointer = PDFAbstractColorSpace::createColorSpace(colorSpaceDictionary, m_document, m_document->getObject(colorSpaceDictionary->getValue(csIndex)));
}
catch (PDFException)
{
// Ignore invalid color spaces
continue;
}
if (!colorSpacePointer)
{

View File

@ -67,11 +67,11 @@ public:
constexpr uint8_t getColorChannelIndexStart() const { return (hasProcessColors() || hasSpotColors()) ? 0 : INVALID_CHANNEL_INDEX; }
constexpr uint8_t getColorChannelIndexEnd() const { return (hasProcessColors() || hasSpotColors()) ? (m_processColors + m_spotColors) : INVALID_CHANNEL_INDEX; }
constexpr uint8_t getShapeChannelIndex() const { return hasShapeChannel() ? getProcessColorChannelCount() + getSpotColorChannelCount() : INVALID_CHANNEL_INDEX; }
constexpr uint8_t getOpacityChannelIndex() const { return hasShapeChannel() ? getProcessColorChannelCount() + getSpotColorChannelCount() + getShapeChannelCount() : INVALID_CHANNEL_INDEX; }
constexpr uint8_t getOpacityChannelIndex() const { return hasOpacityChannel() ? getProcessColorChannelCount() + getSpotColorChannelCount() + getShapeChannelCount() : INVALID_CHANNEL_INDEX; }
/// Pixel format is valid, if we have at least one color channel
/// (it doesn't matter, if it is process color, or spot color)
constexpr bool isValid() const { return getColorChannelCount() > 0; }
constexpr bool isValid() const { return getChannelCount() > 0; }
inline void setProcessColors(const uint8_t& processColors) { m_processColors = processColors; }
inline void setSpotColors(const uint8_t& spotColors) { m_spotColors = spotColors; }
@ -237,7 +237,7 @@ private:
};
/// Ink mapper for mapping device inks (device colors) and spot inks (spot colors).
class PDFInkMapper
class Pdf4QtLIBSHARED_EXPORT PDFInkMapper
{
public:
explicit PDFInkMapper(const PDFDocument* document);
@ -281,7 +281,7 @@ private:
/// page blending space and device blending space. So, painted graphics is being
/// blended to the page blending space, and then converted to the device blending
/// space.
class PDFTransparencyRenderer : public PDFPageContentProcessor
class Pdf4QtLIBSHARED_EXPORT PDFTransparencyRenderer : public PDFPageContentProcessor
{
private:
using BaseClass = PDFPageContentProcessor;
@ -292,13 +292,23 @@ public:
const PDFFontCache* fontCache,
const PDFCMS* cms,
const PDFOptionalContentActivity* optionalContentActivity,
const PDFInkMapper* inkMapper,
QMatrix pagePointToDevicePointMatrix);
/// Sets device color space. This is final color space, to which
/// is painted page transformed.
/// \param colorSpace Color space
void setDeviceColorSpace(PDFColorSpacePointer colorSpace);
/// Sets process color space. This color space is used for blending
/// and intermediate results. If page has transparency group, then
/// blending color space from transparency group is used.
/// \param colorSpace Color space
void setProcessColorSpace(PDFColorSpacePointer colorSpace);
/// Starts painting on the device. This function must be called before page
/// content stream is being processed (and must be called exactly once).
void beginPaint();
void beginPaint(QSize pixelSize);
/// Finishes painting on the device. This function must be called after page
/// content stream is processed and all result graphics is being drawn. Page
@ -345,6 +355,7 @@ private:
PDFColorSpacePointer m_processColorSpace; ///< Process color space (color space, in which is page graphic's blended)
std::unique_ptr<PDFTransparencyGroupGuard> m_pageTransparencyGroupGuard;
std::vector<PDFTransparencyGroupPainterData> m_transparencyGroupDataStack;
const PDFInkMapper* m_inkMapper;
bool m_active;
};

View File

@ -18,14 +18,28 @@
#include "outputpreviewdialog.h"
#include "ui_outputpreviewdialog.h"
#include "pdfcms.h"
#include "pdfrenderer.h"
#include "pdfdrawspacecontroller.h"
namespace pdfplugin
{
OutputPreviewDialog::OutputPreviewDialog(QWidget* parent) :
OutputPreviewDialog::OutputPreviewDialog(const pdf::PDFDocument* document, pdf::PDFWidget* widget, QWidget* parent) :
QDialog(parent),
ui(new Ui::OutputPreviewDialog)
ui(new Ui::OutputPreviewDialog),
m_inkMapper(document),
m_document(document),
m_widget(widget)
{
ui->setupUi(this);
ui->pageIndexScrollBar->setMinimum(1);
ui->pageIndexScrollBar->setValue(1);
ui->pageIndexScrollBar->setMaximum(int(document->getCatalog()->getPageCount()));
m_inkMapper.createSpotColors(true);
updateImage();
}
OutputPreviewDialog::~OutputPreviewDialog()
@ -33,4 +47,32 @@ OutputPreviewDialog::~OutputPreviewDialog()
delete ui;
}
void OutputPreviewDialog::updateImage()
{
const pdf::PDFPage* page = m_document->getCatalog()->getPage(ui->pageIndexScrollBar->value() - 1);
if (!page)
{
ui->imageLabel->setPixmap(QPixmap());
}
QRectF pageRect = page->getRotatedMediaBox();
QSizeF pageSize = pageRect.size();
pageSize.scale(ui->imageLabel->width(), ui->imageLabel->height(), Qt::KeepAspectRatio);
QSize imageSize = pageSize.toSize();
if (!imageSize.isValid())
{
ui->imageLabel->setPixmap(QPixmap());
}
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, pagePointToDevicePoint);
renderer.beginPaint(imageSize);
renderer.processContents();
renderer.endPaint();
}
} // namespace pdfplugin

View File

@ -18,6 +18,10 @@
#ifndef OUTPUTPREVIEWDIALOG_H
#define OUTPUTPREVIEWDIALOG_H
#include "pdfdocument.h"
#include "pdfdrawwidget.h"
#include "pdftransparencyrenderer.h"
#include <QDialog>
namespace Ui
@ -33,11 +37,16 @@ class OutputPreviewDialog : public QDialog
Q_OBJECT
public:
explicit OutputPreviewDialog(QWidget* parent);
explicit OutputPreviewDialog(const pdf::PDFDocument* document, pdf::PDFWidget* widget, QWidget* parent);
virtual ~OutputPreviewDialog() override;
private:
void updateImage();
Ui::OutputPreviewDialog* ui;
pdf::PDFInkMapper m_inkMapper;
const pdf::PDFDocument* m_document;
pdf::PDFWidget* m_widget;
};
} // namespace pdf

View File

@ -48,7 +48,7 @@
</widget>
</item>
<item>
<widget class="QScrollBar" name="verticalScrollBar">
<widget class="QScrollBar" name="pageIndexScrollBar">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>

View File

@ -62,7 +62,7 @@ std::vector<QAction*> OutputPreviewPlugin::getActions() const
void OutputPreviewPlugin::onOutputPreviewTriggered()
{
OutputPreviewDialog dialog(m_widget);
OutputPreviewDialog dialog(m_document, m_widget, m_widget);
dialog.exec();
}