mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Proper active color masking
This commit is contained in:
@ -40,6 +40,11 @@ PDFFloatBitmap::PDFFloatBitmap(size_t width, size_t height, PDFPixelFormat forma
|
||||
Q_ASSERT(format.isValid());
|
||||
|
||||
m_data.resize(format.calculateBitmapDataLength(width, height), static_cast<PDFColorComponent>(0.0f));
|
||||
|
||||
if (m_format.hasActiveColorMask())
|
||||
{
|
||||
m_activeColorMask.resize(width * height, 0);
|
||||
}
|
||||
}
|
||||
|
||||
PDFColorBuffer PDFFloatBitmap::getPixel(size_t x, size_t y)
|
||||
@ -120,9 +125,32 @@ size_t PDFFloatBitmap::getPixelIndex(size_t x, size_t y) const
|
||||
return (y * m_width + x) * m_pixelSize;
|
||||
}
|
||||
|
||||
uint32_t PDFFloatBitmap::getPixelActiveColorMask(size_t x, size_t y) const
|
||||
{
|
||||
Q_ASSERT(hasActiveColorMask());
|
||||
return m_activeColorMask[y * m_width + x];
|
||||
}
|
||||
|
||||
void PDFFloatBitmap::markPixelActiveColorMask(size_t x, size_t y, uint32_t activeColorMask)
|
||||
{
|
||||
Q_ASSERT(hasActiveColorMask());
|
||||
m_activeColorMask[y * m_width + x] |= activeColorMask;
|
||||
}
|
||||
|
||||
void PDFFloatBitmap::setPixelActiveColorMask(size_t x, size_t y, uint32_t activeColorMask)
|
||||
{
|
||||
Q_ASSERT(hasActiveColorMask());
|
||||
m_activeColorMask[y * m_width + x] = activeColorMask;
|
||||
}
|
||||
|
||||
void PDFFloatBitmap::setAllColorActive()
|
||||
{
|
||||
std::fill(m_activeColorMask.begin(), m_activeColorMask.end(), PDFPixelFormat::getAllColorsMask());
|
||||
}
|
||||
|
||||
PDFFloatBitmap PDFFloatBitmap::extractProcessColors() const
|
||||
{
|
||||
PDFPixelFormat format = PDFPixelFormat::createFormat(m_format.getProcessColorChannelCount(), 0, false, m_format.hasProcessColorsSubtractive());
|
||||
PDFPixelFormat format = PDFPixelFormat::createFormat(m_format.getProcessColorChannelCount(), 0, false, m_format.hasProcessColorsSubtractive(), false);
|
||||
PDFFloatBitmap result(getWidth(), getHeight(), format);
|
||||
|
||||
for (size_t x = 0; x < getWidth(); ++x)
|
||||
@ -142,7 +170,7 @@ PDFFloatBitmap PDFFloatBitmap::extractProcessColors() const
|
||||
|
||||
PDFFloatBitmap PDFFloatBitmap::extractSpotChannel(uint8_t channel) const
|
||||
{
|
||||
PDFPixelFormat format = PDFPixelFormat::createFormat(0, 1, false, m_format.hasProcessColorsSubtractive());
|
||||
PDFPixelFormat format = PDFPixelFormat::createFormat(0, 1, false, m_format.hasProcessColorsSubtractive(), false);
|
||||
PDFFloatBitmap result(getWidth(), getHeight(), format);
|
||||
|
||||
Q_ASSERT(m_format.hasSpotColors());
|
||||
@ -172,7 +200,6 @@ void PDFFloatBitmap::blend(const PDFFloatBitmap& source,
|
||||
PDFColorComponent constantAlpha,
|
||||
BlendMode mode,
|
||||
bool knockoutGroup,
|
||||
uint32_t activeColorChannels,
|
||||
OverprintMode overprintMode,
|
||||
QRect blendRegion)
|
||||
{
|
||||
@ -213,6 +240,8 @@ void PDFFloatBitmap::blend(const PDFFloatBitmap& source,
|
||||
// Handle overprint mode for normal blend mode. We do not support
|
||||
// oveprinting for other blend modes, than normal.
|
||||
|
||||
auto getBlendModeForPixel = [&source, &channelBlendModes, pixelFormat, overprintMode, mode](size_t x, size_t y, uint8_t channel)
|
||||
{
|
||||
switch (overprintMode)
|
||||
{
|
||||
case OverprintMode::NoOveprint:
|
||||
@ -222,14 +251,13 @@ void PDFFloatBitmap::blend(const PDFFloatBitmap& source,
|
||||
{
|
||||
// Select source color, if channel is active,
|
||||
// otherwise select backdrop color.
|
||||
for (uint8_t colorChannelIndex = colorChannelStart; colorChannelIndex < colorChannelEnd; ++colorChannelIndex)
|
||||
{
|
||||
uint32_t flag = (static_cast<uint32_t>(1)) << colorChannelIndex;
|
||||
if (channelBlendModes[colorChannelIndex] == BlendMode::Normal && !(activeColorChannels & flag))
|
||||
|
||||
const uint32_t activeColorChannels = source.hasActiveColorMask() ? source.getPixelActiveColorMask(x, y) : PDFPixelFormat::getAllColorsMask();
|
||||
uint32_t flag = (static_cast<uint32_t>(1)) << channel;
|
||||
if (channelBlendModes[channel] == BlendMode::Normal && !(activeColorChannels & flag))
|
||||
{
|
||||
// Color channel is inactive
|
||||
channelBlendModes[colorChannelIndex] = BlendMode::Overprint_SelectBackdrop;
|
||||
}
|
||||
return BlendMode::Overprint_SelectBackdrop;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -240,37 +268,36 @@ void PDFFloatBitmap::blend(const PDFFloatBitmap& source,
|
||||
// For process colors, select source color, if it is nonzero,
|
||||
// otherwise select backdrop. If process color channel is inactive,
|
||||
// select backdrop.
|
||||
if (pixelFormat.hasProcessColors() && mode == BlendMode::Normal)
|
||||
|
||||
const uint32_t activeColorChannels = source.hasActiveColorMask() ? source.getPixelActiveColorMask(x, y) : PDFPixelFormat::getAllColorsMask();
|
||||
|
||||
if (pixelFormat.hasProcessColors() && mode == BlendMode::Normal &&
|
||||
channel >= pixelFormat.getProcessColorChannelIndexStart() && channel < pixelFormat.getProcessColorChannelIndexEnd())
|
||||
{
|
||||
for (uint8_t colorChannelIndex = processColorChannelStart; colorChannelIndex < processColorChannelEnd; ++colorChannelIndex)
|
||||
{
|
||||
uint32_t flag = (static_cast<uint32_t>(1)) << colorChannelIndex;
|
||||
uint32_t flag = (static_cast<uint32_t>(1)) << channel;
|
||||
if (!(activeColorChannels & flag))
|
||||
{
|
||||
// Color channel is inactive
|
||||
channelBlendModes[colorChannelIndex] = BlendMode::Overprint_SelectBackdrop;
|
||||
return BlendMode::Overprint_SelectBackdrop;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Color channel is active, but select source color only, if it is nonzero
|
||||
channelBlendModes[colorChannelIndex] = pixelFormat.hasSpotColorsSubtractive() ? BlendMode::Overprint_SelectNonOneSourceOrBackdrop
|
||||
return pixelFormat.hasSpotColorsSubtractive() ? BlendMode::Overprint_SelectNonOneSourceOrBackdrop
|
||||
: BlendMode::Overprint_SelectNonZeroSourceOrBackdrop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pixelFormat.hasSpotColors())
|
||||
if (pixelFormat.hasSpotColors() && channel >= pixelFormat.getSpotColorChannelIndexStart() && channel < pixelFormat.getSpotColorChannelIndexEnd())
|
||||
{
|
||||
// For spot colors, select backdrop, if channel is inactive,
|
||||
// otherwise select source color.
|
||||
for (uint8_t colorChannelIndex = spotColorChannelStart; colorChannelIndex < spotColorChannelEnd; ++colorChannelIndex)
|
||||
{
|
||||
uint32_t flag = (static_cast<uint32_t>(1)) << colorChannelIndex;
|
||||
if (channelBlendModes[colorChannelIndex] == BlendMode::Normal && !(activeColorChannels & flag))
|
||||
|
||||
uint32_t flag = (static_cast<uint32_t>(1)) << channel;
|
||||
if (channelBlendModes[channel] == BlendMode::Normal && !(activeColorChannels & flag))
|
||||
{
|
||||
// Color channel is inactive
|
||||
channelBlendModes[colorChannelIndex] = BlendMode::Overprint_SelectBackdrop;
|
||||
}
|
||||
return BlendMode::Overprint_SelectBackdrop;
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,6 +311,9 @@ void PDFFloatBitmap::blend(const PDFFloatBitmap& source,
|
||||
}
|
||||
}
|
||||
|
||||
return channelBlendModes[channel];
|
||||
};
|
||||
|
||||
for (size_t x = blendRegion.left(); x <= blendRegion.right(); ++x)
|
||||
{
|
||||
for (size_t y = blendRegion.top(); y <= blendRegion.bottom(); ++y)
|
||||
@ -348,14 +378,16 @@ void PDFFloatBitmap::blend(const PDFFloatBitmap& source,
|
||||
{
|
||||
for (uint8_t i = pixelFormat.getProcessColorChannelIndexStart(); i < pixelFormat.getProcessColorChannelIndexEnd(); ++i)
|
||||
{
|
||||
B_i[i] = PDFBlendFunction::blend(channelBlendModes[i], backdropColor[i], sourceColor[i]);
|
||||
const BlendMode pixelBlendMode = getBlendModeForPixel(x, y, i);
|
||||
B_i[i] = PDFBlendFunction::blend(pixelBlendMode, backdropColor[i], sourceColor[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint8_t i = pixelFormat.getProcessColorChannelIndexStart(); i < pixelFormat.getProcessColorChannelIndexEnd(); ++i)
|
||||
{
|
||||
B_i[i] = 1.0f - PDFBlendFunction::blend(channelBlendModes[i], 1.0f - backdropColor[i], 1.0f - sourceColor[i]);
|
||||
const BlendMode pixelBlendMode = getBlendModeForPixel(x, y, i);
|
||||
B_i[i] = 1.0f - PDFBlendFunction::blend(pixelBlendMode, 1.0f - backdropColor[i], 1.0f - sourceColor[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -367,14 +399,16 @@ void PDFFloatBitmap::blend(const PDFFloatBitmap& source,
|
||||
{
|
||||
for (uint8_t i = pixelFormat.getSpotColorChannelIndexStart(); i < pixelFormat.getSpotColorChannelIndexEnd(); ++i)
|
||||
{
|
||||
B_i[i] = PDFBlendFunction::blend(channelBlendModes[i], backdropColor[i], sourceColor[i]);
|
||||
const BlendMode pixelBlendMode = getBlendModeForPixel(x, y, i);
|
||||
B_i[i] = PDFBlendFunction::blend(pixelBlendMode, backdropColor[i], sourceColor[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint8_t i = pixelFormat.getSpotColorChannelIndexStart(); i < pixelFormat.getSpotColorChannelIndexEnd(); ++i)
|
||||
{
|
||||
B_i[i] = 1.0f - PDFBlendFunction::blend(channelBlendModes[i], 1.0f - backdropColor[i], 1.0f - sourceColor[i]);
|
||||
const BlendMode pixelBlendMode = getBlendModeForPixel(x, y, i);
|
||||
B_i[i] = 1.0f - PDFBlendFunction::blend(pixelBlendMode, 1.0f - backdropColor[i], 1.0f - sourceColor[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -447,14 +481,16 @@ void PDFFloatBitmap::blend(const PDFFloatBitmap& source,
|
||||
{
|
||||
for (uint8_t i = pixelFormat.getSpotColorChannelIndexStart(); i < pixelFormat.getSpotColorChannelIndexEnd(); ++i)
|
||||
{
|
||||
B_i[i] = PDFBlendFunction::blend(channelBlendModes[i], backdropColor[i], sourceColor[i]);
|
||||
const BlendMode pixelBlendMode = getBlendModeForPixel(x, y, i);
|
||||
B_i[i] = PDFBlendFunction::blend(pixelBlendMode, backdropColor[i], sourceColor[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint8_t i = pixelFormat.getSpotColorChannelIndexStart(); i < pixelFormat.getSpotColorChannelIndexEnd(); ++i)
|
||||
{
|
||||
B_i[i] = 1.0f - PDFBlendFunction::blend(channelBlendModes[i], 1.0f - backdropColor[i], 1.0f - sourceColor[i]);
|
||||
const BlendMode pixelBlendMode = getBlendModeForPixel(x, y, i);
|
||||
B_i[i] = 1.0f - PDFBlendFunction::blend(pixelBlendMode, 1.0f - backdropColor[i], 1.0f - sourceColor[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -574,7 +610,7 @@ void PDFFloatBitmapWithColorSpace::convertToColorSpace(const PDFCMS* cms,
|
||||
newFormat.setProcessColorsSubtractive(targetDeviceColors == 4);
|
||||
|
||||
PDFFloatBitmap sourceProcessColors = extractProcessColors();
|
||||
PDFFloatBitmap targetProcessColors(sourceProcessColors.getWidth(), sourceProcessColors.getHeight(), PDFPixelFormat::createFormat(targetDeviceColors, 0, false, newFormat.hasProcessColorsSubtractive()));
|
||||
PDFFloatBitmap targetProcessColors(sourceProcessColors.getWidth(), sourceProcessColors.getHeight(), PDFPixelFormat::createFormat(targetDeviceColors, 0, false, newFormat.hasProcessColorsSubtractive(), newFormat.hasActiveColorMask()));
|
||||
|
||||
if (!PDFAbstractColorSpace::transform(m_colorSpace.data(), targetColorSpace.data(), cms, intent, sourceProcessColors.getPixels(), targetProcessColors.getPixels(), reporter))
|
||||
{
|
||||
@ -605,6 +641,8 @@ void PDFFloatBitmapWithColorSpace::convertToColorSpace(const PDFCMS* cms,
|
||||
}
|
||||
}
|
||||
|
||||
// Simplification - set all color channels active
|
||||
temporary.setAllColorActive();
|
||||
*this = qMove(temporary);
|
||||
}
|
||||
|
||||
@ -659,7 +697,8 @@ void PDFTransparencyRenderer::beginPaint(QSize pixelSize)
|
||||
|
||||
PDFPixelFormat pixelFormat = PDFPixelFormat::createFormat(uint8_t(m_deviceColorSpace->getColorComponentCount()),
|
||||
uint8_t(m_inkMapper->getActiveSpotColorCount()),
|
||||
true, m_deviceColorSpace->getColorComponentCount() == 4);
|
||||
true, m_deviceColorSpace->getColorComponentCount() == 4,
|
||||
true);
|
||||
|
||||
PDFFloatBitmapWithColorSpace paper = PDFFloatBitmapWithColorSpace(pixelSize.width(), pixelSize.height(), pixelFormat, m_deviceColorSpace);
|
||||
paper.makeColorWhite();
|
||||
@ -798,7 +837,7 @@ QImage PDFTransparencyRenderer::toImage(bool use16Bit, bool usePaper, PDFRGB pap
|
||||
softMask.makeOpaque();
|
||||
|
||||
QRect blendRegion(0, 0, int(floatImage.getWidth()), int(floatImage.getHeight()));
|
||||
PDFFloatBitmapWithColorSpace::blend(floatImage, paperImage, paperImage, paperImage, softMask, false, 1.0f, BlendMode::Normal, false, 0xFFFF, PDFFloatBitmap::OverprintMode::NoOveprint, blendRegion);
|
||||
PDFFloatBitmapWithColorSpace::blend(floatImage, paperImage, paperImage, paperImage, softMask, false, 1.0f, BlendMode::Normal, false, PDFFloatBitmap::OverprintMode::NoOveprint, blendRegion);
|
||||
|
||||
return toImageImpl(paperImage, use16Bit);
|
||||
}
|
||||
@ -836,6 +875,8 @@ void PDFTransparencyRenderer::performPixelSampling(const PDFReal shape,
|
||||
{
|
||||
pixel[colorChannelIndex] = fillColor.mappedColor[colorChannelIndex];
|
||||
}
|
||||
|
||||
m_drawBuffer.markPixelActiveColorMask(x, y, fillColor.activeChannels);
|
||||
}
|
||||
}
|
||||
|
||||
@ -863,7 +904,7 @@ void PDFTransparencyRenderer::collapseSpotColorsToDeviceColors(PDFFloatBitmapWit
|
||||
{
|
||||
case PDFAbstractColorSpace::ColorSpace::Separation:
|
||||
{
|
||||
PDFFloatBitmap processColorBitmap(spotColorBitmap.getWidth(), spotColorBitmap.getHeight(), PDFPixelFormat::createFormat(pixelFormat.getProcessColorChannelCount(), 0, false, pixelFormat.hasProcessColorsSubtractive()));
|
||||
PDFFloatBitmap processColorBitmap(spotColorBitmap.getWidth(), spotColorBitmap.getHeight(), PDFPixelFormat::createFormat(pixelFormat.getProcessColorChannelCount(), 0, false, pixelFormat.hasProcessColorsSubtractive(), false));
|
||||
if (!PDFAbstractColorSpace::transform(spotColor->colorSpace.data(), bitmap.getColorSpace().data(), getCMS(), getGraphicState()->getRenderingIntent(), spotColorBitmap.getPixels(), processColorBitmap.getPixels(), this))
|
||||
{
|
||||
reportRenderError(RenderErrorType::Error, PDFTranslationContext::tr("Transformation of spot color to blend color space failed."));
|
||||
@ -955,7 +996,6 @@ void PDFTransparencyRenderer::performPathPainting(const QPainterPath& path, bool
|
||||
}
|
||||
}
|
||||
|
||||
m_drawBuffer.markActiveColors(fillColor.activeChannels);
|
||||
m_drawBuffer.modify(fillRect, true, false);
|
||||
}
|
||||
}
|
||||
@ -1028,7 +1068,6 @@ void PDFTransparencyRenderer::performPathPainting(const QPainterPath& path, bool
|
||||
}
|
||||
}
|
||||
|
||||
m_drawBuffer.markActiveColors(strokeColor.activeChannels);
|
||||
m_drawBuffer.modify(strokeRect, false, true);
|
||||
}
|
||||
}
|
||||
@ -1216,9 +1255,18 @@ void PDFTransparencyRenderer::performEndTransparencyGroup(ProcessOrder order, co
|
||||
PDFTransparencyGroupPainterData& targetData = m_transparencyGroupDataStack.back();
|
||||
sourceData.immediateBackdrop.convertToColorSpace(getCMS(), targetData.renderingIntent, targetData.blendColorSpace, this);
|
||||
|
||||
PDFOverprintMode overprintMode = getGraphicState()->getOverprintMode();
|
||||
const bool useOverprint = overprintMode.overprintFilling || overprintMode.overprintStroking;
|
||||
|
||||
PDFFloatBitmap::OverprintMode selectedOverprintMode = PDFFloatBitmap::OverprintMode::NoOveprint;
|
||||
if (useOverprint)
|
||||
{
|
||||
selectedOverprintMode = overprintMode.overprintMode == 0 ? PDFFloatBitmap::OverprintMode::Overprint_Mode_0
|
||||
: PDFFloatBitmap::OverprintMode::Overprint_Mode_1;
|
||||
}
|
||||
|
||||
PDFFloatBitmap::blend(sourceData.immediateBackdrop, targetData.immediateBackdrop, *getBackdrop(), *getInitialBackdrop(), sourceData.softMask,
|
||||
sourceData.alphaIsShape, sourceData.alphaFill, BlendMode::Normal, targetData.group.knockout, 0xFFFF,
|
||||
PDFFloatBitmap::OverprintMode::NoOveprint, getPaintRect());
|
||||
sourceData.alphaIsShape, sourceData.alphaFill, BlendMode::Normal, targetData.group.knockout, selectedOverprintMode, getPaintRect());
|
||||
|
||||
// Create draw buffer
|
||||
PDFFloatBitmapWithColorSpace* backdrop = getImmediateBackdrop();
|
||||
@ -1537,7 +1585,7 @@ void PDFTransparencyRenderer::flushDrawBuffer()
|
||||
|
||||
PDFFloatBitmap::blend(m_drawBuffer, *getImmediateBackdrop(), *getBackdrop(), *getInitialBackdrop(), m_painterStateStack.top().softMask,
|
||||
getGraphicState()->getAlphaIsShape(), 1.0f, getGraphicState()->getBlendMode(), isTransparencyGroupKnockout(),
|
||||
m_drawBuffer.getActiveColors(), selectedOverprintMode, m_drawBuffer.getModifiedRect());
|
||||
selectedOverprintMode, m_drawBuffer.getModifiedRect());
|
||||
|
||||
|
||||
m_drawBuffer.clear();
|
||||
@ -2204,11 +2252,6 @@ void PDFPainterPathSampler::createScanLineSample(const QPointF& p1, const QPoint
|
||||
}
|
||||
}
|
||||
|
||||
void PDFDrawBuffer::markActiveColors(uint32_t activeColors)
|
||||
{
|
||||
m_activeColors |= activeColors;
|
||||
}
|
||||
|
||||
void PDFDrawBuffer::clear()
|
||||
{
|
||||
if (!m_modifiedRect.isValid())
|
||||
@ -2222,10 +2265,10 @@ void PDFDrawBuffer::clear()
|
||||
{
|
||||
PDFColorBuffer buffer = getPixel(x, y);
|
||||
std::fill(buffer.begin(), buffer.end(), 0.0f);
|
||||
setPixelActiveColorMask(x, y, 0);
|
||||
}
|
||||
}
|
||||
|
||||
m_activeColors = 0;
|
||||
m_containsFilling = false;
|
||||
m_containsStroking = false;
|
||||
m_modifiedRect = QRect();
|
||||
|
@ -50,6 +50,7 @@ public:
|
||||
constexpr bool hasOpacityChannel() const { return m_flags & FLAG_HAS_OPACITY_CHANNEL; }
|
||||
constexpr bool hasProcessColorsSubtractive() const { return m_flags & FLAG_PROCESS_COLORS_SUBTRACTIVE; }
|
||||
constexpr bool hasSpotColorsSubtractive() const { return true; }
|
||||
constexpr bool hasActiveColorMask() const { return m_flags & FLAG_HAS_ACTIVE_COLOR_MASK; }
|
||||
|
||||
constexpr uint8_t getFlags() const { return m_flags; }
|
||||
constexpr uint8_t getMaximalColorChannelCount() const { return 32; }
|
||||
@ -89,9 +90,9 @@ public:
|
||||
}
|
||||
|
||||
static constexpr PDFPixelFormat createOpacityMask() { return PDFPixelFormat(0, 0, FLAG_HAS_OPACITY_CHANNEL); }
|
||||
static constexpr PDFPixelFormat createFormatDefaultGray(uint8_t spotColors) { return createFormat(1, spotColors, true, false); }
|
||||
static constexpr PDFPixelFormat createFormatDefaultRGB(uint8_t spotColors) { return createFormat(3, spotColors, true, false); }
|
||||
static constexpr PDFPixelFormat createFormatDefaultCMYK(uint8_t spotColors) { return createFormat(4, spotColors, true, true); }
|
||||
static constexpr PDFPixelFormat createFormatDefaultGray(uint8_t spotColors) { return createFormat(1, spotColors, true, false, false); }
|
||||
static constexpr PDFPixelFormat createFormatDefaultRGB(uint8_t spotColors) { return createFormat(3, spotColors, true, false, false); }
|
||||
static constexpr PDFPixelFormat createFormatDefaultCMYK(uint8_t spotColors) { return createFormat(4, spotColors, true, true, false); }
|
||||
|
||||
static constexpr PDFPixelFormat removeProcessColors(PDFPixelFormat format) { return PDFPixelFormat(0, format.getSpotColorChannelCount(), format.getFlags()); }
|
||||
static constexpr PDFPixelFormat removeSpotColors(PDFPixelFormat format) { return PDFPixelFormat(format.getProcessColorChannelCount(), 0, format.getFlags()); }
|
||||
@ -99,9 +100,12 @@ public:
|
||||
|
||||
static constexpr uint32_t getAllColorsMask() { return 0xFFFF; }
|
||||
|
||||
static constexpr PDFPixelFormat createFormat(uint8_t processColors, uint8_t spotColors, bool withShapeAndOpacity, bool processColorSubtractive)
|
||||
static constexpr PDFPixelFormat createFormat(uint8_t processColors, uint8_t spotColors, bool withShapeAndOpacity, bool processColorSubtractive, bool hasActiveColorMask)
|
||||
{
|
||||
return PDFPixelFormat(processColors, spotColors, (withShapeAndOpacity ? FLAG_HAS_SHAPE_CHANNEL + FLAG_HAS_OPACITY_CHANNEL : 0) + (processColorSubtractive ? FLAG_PROCESS_COLORS_SUBTRACTIVE : 0));
|
||||
const uint8_t flags = (withShapeAndOpacity ? FLAG_HAS_SHAPE_CHANNEL + FLAG_HAS_OPACITY_CHANNEL : 0) +
|
||||
(processColorSubtractive ? FLAG_PROCESS_COLORS_SUBTRACTIVE : 0) +
|
||||
(hasActiveColorMask ? FLAG_HAS_ACTIVE_COLOR_MASK : 0);
|
||||
return PDFPixelFormat(processColors, spotColors, flags);
|
||||
}
|
||||
|
||||
/// Calculates bitmap data length required to store bitmapt with given pixel format.
|
||||
@ -121,6 +125,7 @@ private:
|
||||
constexpr static uint8_t FLAG_HAS_SHAPE_CHANNEL = 0x01;
|
||||
constexpr static uint8_t FLAG_HAS_OPACITY_CHANNEL = 0x02;
|
||||
constexpr static uint8_t FLAG_PROCESS_COLORS_SUBTRACTIVE = 0x04;
|
||||
constexpr static uint8_t FLAG_HAS_ACTIVE_COLOR_MASK = 0x08;
|
||||
|
||||
uint8_t m_processColors = 0;
|
||||
uint8_t m_spotColors = 0;
|
||||
@ -176,6 +181,30 @@ public:
|
||||
/// \param y Vertical coordinate of the pixel
|
||||
size_t getPixelIndex(size_t x, size_t y) const;
|
||||
|
||||
/// Returns true, if bitmap has active color mask
|
||||
bool hasActiveColorMask() const { return !m_activeColorMask.empty(); }
|
||||
|
||||
/// Get color mask for given pixel. This function must be called
|
||||
/// only on bitmaps, which use active color mask.
|
||||
/// \param x Horizontal coordinate of the pixel
|
||||
/// \param y Vertical coordinate of the pixel
|
||||
uint32_t getPixelActiveColorMask(size_t x, size_t y) const;
|
||||
|
||||
/// Marks active color channels for given pixel as active
|
||||
/// \param x Horizontal coordinate of the pixel
|
||||
/// \param y Vertical coordinate of the pixel
|
||||
/// \param activeColorMask Active color mask
|
||||
void markPixelActiveColorMask(size_t x, size_t y, uint32_t activeColorMask);
|
||||
|
||||
/// Sets active color channels for given pixel
|
||||
/// \param x Horizontal coordinate of the pixel
|
||||
/// \param y Vertical coordinate of the pixel
|
||||
/// \param activeColorMask Active color mask
|
||||
void setPixelActiveColorMask(size_t x, size_t y, uint32_t activeColorMask);
|
||||
|
||||
/// Sets all colors as active
|
||||
void setAllColorActive();
|
||||
|
||||
/// Extract process colors into another bitmap
|
||||
PDFFloatBitmap extractProcessColors() const;
|
||||
|
||||
@ -204,7 +233,6 @@ public:
|
||||
/// \param alphaIsShape Both soft mask and constant alpha are shapes and not opacity?
|
||||
/// \param constantAlpha Constant alpha, can mean shape or opacity
|
||||
/// \param mode Blend mode
|
||||
/// \param activeColorChannels Active color channels
|
||||
/// \param overprintMode Overprint mode
|
||||
/// \param blendRegion Blend region
|
||||
static void blend(const PDFFloatBitmap& source,
|
||||
@ -216,7 +244,6 @@ public:
|
||||
PDFColorComponent constantAlpha,
|
||||
BlendMode mode,
|
||||
bool knockoutGroup,
|
||||
uint32_t activeColorChannels,
|
||||
OverprintMode overprintMode,
|
||||
QRect blendRegion);
|
||||
|
||||
@ -234,6 +261,7 @@ private:
|
||||
std::size_t m_height;
|
||||
std::size_t m_pixelSize;
|
||||
std::vector<PDFColorComponent> m_data;
|
||||
std::vector<uint32_t> m_activeColorMask;
|
||||
};
|
||||
|
||||
/// Float bitmap with color space
|
||||
@ -436,9 +464,6 @@ class PDFDrawBuffer : public PDFFloatBitmap
|
||||
public:
|
||||
using PDFFloatBitmap::PDFFloatBitmap;
|
||||
|
||||
/// Marks color channels as active
|
||||
void markActiveColors(uint32_t activeColors);
|
||||
|
||||
/// Clears the draw buffer
|
||||
void clear();
|
||||
|
||||
@ -448,9 +473,6 @@ public:
|
||||
/// Returns true, if draw buffer is modified and needs to be flushed
|
||||
bool isModified() const { return m_modifiedRect.isValid(); }
|
||||
|
||||
/// Returns active colors
|
||||
uint32_t getActiveColors() const { return m_activeColors; }
|
||||
|
||||
/// Returns modified rectangle
|
||||
QRect getModifiedRect() const { return m_modifiedRect; }
|
||||
|
||||
@ -458,7 +480,6 @@ public:
|
||||
bool isContainsStroking() const { return m_containsStroking; }
|
||||
|
||||
private:
|
||||
uint32_t m_activeColors = 0;
|
||||
bool m_containsFilling = false;
|
||||
bool m_containsStroking = false;
|
||||
QRect m_modifiedRect;
|
||||
|
Reference in New Issue
Block a user