mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Spot color mapping
This commit is contained in:
@ -99,6 +99,7 @@ bool PDFBlendModeInfo::isSeparable(BlendMode mode)
|
|||||||
case BlendMode::Compatible:
|
case BlendMode::Compatible:
|
||||||
case BlendMode::Overprint_SelectBackdrop:
|
case BlendMode::Overprint_SelectBackdrop:
|
||||||
case BlendMode::Overprint_SelectNonZeroSourceOrBackdrop:
|
case BlendMode::Overprint_SelectNonZeroSourceOrBackdrop:
|
||||||
|
case BlendMode::Overprint_SelectNonOneSourceOrBackdrop:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case BlendMode::Hue:
|
case BlendMode::Hue:
|
||||||
@ -354,6 +355,16 @@ PDFColorComponent PDFBlendFunction::blend(BlendMode mode, PDFColorComponent Cb,
|
|||||||
return Cs;
|
return Cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case BlendMode::Overprint_SelectNonOneSourceOrBackdrop:
|
||||||
|
{
|
||||||
|
if (qFuzzyIsNull(1.0f - Cs))
|
||||||
|
{
|
||||||
|
return Cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Cs;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
|
@ -54,6 +54,7 @@ enum class BlendMode
|
|||||||
// Special blend modes for handling overprint. Used only internally.
|
// Special blend modes for handling overprint. Used only internally.
|
||||||
Overprint_SelectBackdrop,
|
Overprint_SelectBackdrop,
|
||||||
Overprint_SelectNonZeroSourceOrBackdrop,
|
Overprint_SelectNonZeroSourceOrBackdrop,
|
||||||
|
Overprint_SelectNonOneSourceOrBackdrop,
|
||||||
|
|
||||||
// Invalid blending mode - for internal purposes only
|
// Invalid blending mode - for internal purposes only
|
||||||
Invalid
|
Invalid
|
||||||
|
@ -215,7 +215,8 @@ void PDFFloatBitmap::blend(const PDFFloatBitmap& source,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Color channel is active, but select source color only, if it is nonzero
|
// Color channel is active, but select source color only, if it is nonzero
|
||||||
channelBlendModes[colorChannelIndex] = BlendMode::Overprint_SelectNonZeroSourceOrBackdrop;
|
channelBlendModes[colorChannelIndex] = pixelFormat.hasSpotColorsSubtractive() ? BlendMode::Overprint_SelectNonOneSourceOrBackdrop
|
||||||
|
: BlendMode::Overprint_SelectNonZeroSourceOrBackdrop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -752,4 +753,105 @@ bool PDFTransparencyRenderer::isTransparencyGroupKnockout() const
|
|||||||
return m_transparencyGroupDataStack.back().group.knockout;
|
return m_transparencyGroupDataStack.back().group.knockout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDFInkMapper::PDFInkMapper(const PDFDocument* document) :
|
||||||
|
m_document(document)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDFInkMapper::createSpotColors(bool activate)
|
||||||
|
{
|
||||||
|
m_spotColors.clear();
|
||||||
|
|
||||||
|
const PDFCatalog* catalog = m_document->getCatalog();
|
||||||
|
const size_t pageCount = catalog->getPageCount();
|
||||||
|
for (size_t i = 0; i < pageCount; ++i)
|
||||||
|
{
|
||||||
|
const PDFPage* page = catalog->getPage(i);
|
||||||
|
PDFObject resources = m_document->getObject(page->getResources());
|
||||||
|
|
||||||
|
if (resources.isDictionary() && resources.getDictionary()->hasKey("ColorSpace"))
|
||||||
|
{
|
||||||
|
const PDFDictionary* colorSpaceDictionary = m_document->getDictionaryFromObject(resources.getDictionary()->get("ColorSpace"));
|
||||||
|
if (colorSpaceDictionary)
|
||||||
|
{
|
||||||
|
std::size_t colorSpaces = colorSpaceDictionary->getCount();
|
||||||
|
for (size_t csIndex = 0; csIndex < colorSpaces; ++ csIndex)
|
||||||
|
{
|
||||||
|
PDFColorSpacePointer colorSpacePointer = PDFAbstractColorSpace::createColorSpace(colorSpaceDictionary, m_document, colorSpaceDictionary->getValue(csIndex));
|
||||||
|
|
||||||
|
if (!colorSpacePointer)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (colorSpacePointer->getColorSpace())
|
||||||
|
{
|
||||||
|
case PDFAbstractColorSpace::ColorSpace::Separation:
|
||||||
|
{
|
||||||
|
const PDFSeparationColorSpace* separationColorSpace = dynamic_cast<const PDFSeparationColorSpace*>(colorSpacePointer.data());
|
||||||
|
|
||||||
|
if (!separationColorSpace->isNone() && !separationColorSpace->isAll() && !separationColorSpace->getColorName().isEmpty())
|
||||||
|
{
|
||||||
|
// Try to add spot color
|
||||||
|
const QByteArray& colorName = separationColorSpace->getColorName();
|
||||||
|
if (!containsSpotColor(colorName))
|
||||||
|
{
|
||||||
|
SpotColorInfo info;
|
||||||
|
info.name = colorName;
|
||||||
|
info.colorSpace = colorSpacePointer;
|
||||||
|
m_spotColors.emplace_back(qMove(info));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PDFAbstractColorSpace::ColorSpace::DeviceN:
|
||||||
|
{
|
||||||
|
const PDFDeviceNColorSpace* deviceNColorSpace = dynamic_cast<const PDFDeviceNColorSpace*>(colorSpacePointer.data());
|
||||||
|
|
||||||
|
if (!deviceNColorSpace->isNone())
|
||||||
|
{
|
||||||
|
const PDFDeviceNColorSpace::Colorants& colorants = deviceNColorSpace->getColorants();
|
||||||
|
for (size_t i = 0; i < colorants.size(); ++i)
|
||||||
|
{
|
||||||
|
const PDFDeviceNColorSpace::ColorantInfo& colorantInfo = colorants[i];
|
||||||
|
if (!containsSpotColor(colorantInfo.name))
|
||||||
|
{
|
||||||
|
SpotColorInfo info;
|
||||||
|
info.name = colorantInfo.name;
|
||||||
|
info.index = i;
|
||||||
|
info.colorSpace = colorSpacePointer;
|
||||||
|
m_spotColors.emplace_back(qMove(info));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activate)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PDFInkMapper::containsSpotColor(const QByteArray& colorName) const
|
||||||
|
{
|
||||||
|
return getSpotColor(colorName) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "pdfglobal.h"
|
#include "pdfglobal.h"
|
||||||
#include "pdfcolorspaces.h"
|
#include "pdfcolorspaces.h"
|
||||||
#include "pdfpagecontentprocessor.h"
|
#include "pdfpagecontentprocessor.h"
|
||||||
|
#include "pdfconstants.h"
|
||||||
|
|
||||||
namespace pdf
|
namespace pdf
|
||||||
{
|
{
|
||||||
@ -235,6 +236,38 @@ private:
|
|||||||
PDFColorSpacePointer m_colorSpace;
|
PDFColorSpacePointer m_colorSpace;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Ink mapper for mapping device inks (device colors) and spot inks (spot colors).
|
||||||
|
class PDFInkMapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit PDFInkMapper(const PDFDocument* document);
|
||||||
|
|
||||||
|
struct SpotColorInfo
|
||||||
|
{
|
||||||
|
QByteArray name;
|
||||||
|
uint32_t index = 0; ///< Index into DeviceN color space (index of colorant)
|
||||||
|
PDFColorSpacePointer colorSpace;
|
||||||
|
bool active = false; ///< Is spot color active?
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/// Scan document for spot colors and fills color info
|
||||||
|
/// \param activate Set spot colors active?
|
||||||
|
void createSpotColors(bool activate);
|
||||||
|
|
||||||
|
/// Returns true, if mapper contains given spot color
|
||||||
|
/// \param colorName Color name
|
||||||
|
bool containsSpotColor(const QByteArray& colorName) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
const PDFDocument* m_document;
|
||||||
|
std::vector<SpotColorInfo> m_spotColors;
|
||||||
|
};
|
||||||
|
|
||||||
/// Renders PDF pages with transparency, using 32-bit floating point precision.
|
/// Renders PDF pages with transparency, using 32-bit floating point precision.
|
||||||
/// Both device color space and blending color space can be defined. It implements
|
/// Both device color space and blending color space can be defined. It implements
|
||||||
/// page blending space and device blending space. So, painted graphics is being
|
/// page blending space and device blending space. So, painted graphics is being
|
||||||
|
Reference in New Issue
Block a user