mirror of https://github.com/JakubMelka/PDF4QT.git
Draw buffer commiting
This commit is contained in:
parent
6a9cc5c5d6
commit
f0b1707d12
|
@ -149,7 +149,8 @@ void PDFFloatBitmap::blend(const PDFFloatBitmap& source,
|
|||
BlendMode mode,
|
||||
bool knockoutGroup,
|
||||
uint32_t activeColorChannels,
|
||||
OverprintMode overprintMode)
|
||||
OverprintMode overprintMode,
|
||||
QRect blendRegion)
|
||||
{
|
||||
Q_ASSERT(source.getWidth() == target.getWidth());
|
||||
Q_ASSERT(source.getHeight() == target.getHeight());
|
||||
|
@ -158,8 +159,11 @@ void PDFFloatBitmap::blend(const PDFFloatBitmap& source,
|
|||
Q_ASSERT(source.getHeight() == softMask.getHeight());
|
||||
Q_ASSERT(softMask.getPixelFormat() == PDFPixelFormat::createOpacityMask());
|
||||
|
||||
const size_t width = source.getWidth();
|
||||
const size_t height = source.getHeight();
|
||||
Q_ASSERT(blendRegion.left() >= 0);
|
||||
Q_ASSERT(blendRegion.top() >= 0);
|
||||
Q_ASSERT(blendRegion.right() < source.getWidth());
|
||||
Q_ASSERT(blendRegion.bottom() < source.getHeight());
|
||||
|
||||
const PDFPixelFormat pixelFormat = source.getPixelFormat();
|
||||
const uint8_t shapeChannel = pixelFormat.getShapeChannelIndex();
|
||||
const uint8_t opacityChannel = pixelFormat.getOpacityChannelIndex();
|
||||
|
@ -256,9 +260,9 @@ void PDFFloatBitmap::blend(const PDFFloatBitmap& source,
|
|||
}
|
||||
}
|
||||
|
||||
for (size_t x = 0; x < width; ++x)
|
||||
for (size_t x = blendRegion.left(); x <= blendRegion.right(); ++x)
|
||||
{
|
||||
for (size_t y = 0; y < height; ++y)
|
||||
for (size_t y = blendRegion.top(); y <= blendRegion.bottom(); ++y)
|
||||
{
|
||||
PDFConstColorBuffer sourceColor = source.getPixel(x, y);
|
||||
PDFColorBuffer targetColor = target.getPixel(x, y);
|
||||
|
@ -600,6 +604,8 @@ void PDFTransparencyRenderer::beginPaint(QSize pixelSize)
|
|||
|
||||
m_transparencyGroupDataStack.clear();
|
||||
m_painterStateStack.push(PDFTransparencyPainterState());
|
||||
m_painterStateStack.top().softMask = PDFFloatBitmap(pixelSize.width(), pixelSize.height(), PDFPixelFormat::createOpacityMask());
|
||||
m_painterStateStack.top().softMask.makeOpaque();
|
||||
|
||||
PDFPixelFormat pixelFormat = PDFPixelFormat::createFormat(uint8_t(m_deviceColorSpace->getColorComponentCount()),
|
||||
uint8_t(m_inkMapper->getActiveSpotColorCount()),
|
||||
|
@ -719,6 +725,8 @@ QImage PDFTransparencyRenderer::toImage(bool use16Bit) const
|
|||
|
||||
void PDFTransparencyRenderer::performPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule)
|
||||
{
|
||||
Q_UNUSED(fillRule);
|
||||
|
||||
PDFPainterPathSampler clipSampler(m_painterStateStack.top().clipPath, m_settings.samplesCount, 1.0f);
|
||||
|
||||
QMatrix worldMatrix = getCurrentWorldMatrix();
|
||||
|
@ -776,7 +784,7 @@ void PDFTransparencyRenderer::performPathPainting(const QPainterPath& path, bool
|
|||
}
|
||||
|
||||
m_drawBuffer.markActiveColors(fillColor.activeChannels);
|
||||
m_drawBuffer.modify(fillRect);
|
||||
m_drawBuffer.modify(fillRect, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -784,12 +792,12 @@ void PDFTransparencyRenderer::performPathPainting(const QPainterPath& path, bool
|
|||
{
|
||||
// We must stroke the path.
|
||||
QPainterPathStroker stroker;
|
||||
stroker.setCapStyle(m_graphicState.getLineCapStyle());
|
||||
stroker.setWidth(m_graphicState.getLineWidth());
|
||||
stroker.setMiterLimit(m_graphicState.getMitterLimit());
|
||||
stroker.setJoinStyle(m_graphicState.getLineJoinStyle());
|
||||
stroker.setCapStyle(getGraphicState()->getLineCapStyle());
|
||||
stroker.setWidth(getGraphicState()->getLineWidth());
|
||||
stroker.setMiterLimit(getGraphicState()->getMitterLimit());
|
||||
stroker.setJoinStyle(getGraphicState()->getLineJoinStyle());
|
||||
|
||||
const PDFLineDashPattern& lineDashPattern = m_graphicState.getLineDashPattern();
|
||||
const PDFLineDashPattern& lineDashPattern = getGraphicState()->getLineDashPattern();
|
||||
if (!lineDashPattern.isSolid())
|
||||
{
|
||||
stroker.setDashPattern(QVector<PDFReal>::fromStdVector(lineDashPattern.getDashArray()));
|
||||
|
@ -834,7 +842,7 @@ void PDFTransparencyRenderer::performPathPainting(const QPainterPath& path, bool
|
|||
}
|
||||
|
||||
m_drawBuffer.markActiveColors(strokeColor.activeChannels);
|
||||
m_drawBuffer.modify(strokeRect);
|
||||
m_drawBuffer.modify(strokeRect, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -983,7 +991,8 @@ void PDFTransparencyRenderer::performEndTransparencyGroup(ProcessOrder order, co
|
|||
sourceData.immediateBackdrop.convertToColorSpace(getCMS(), targetData.renderingIntent, targetData.blendColorSpace, this);
|
||||
|
||||
PDFFloatBitmap::blend(sourceData.immediateBackdrop, targetData.immediateBackdrop, *getBackdrop(), *getInitialBackdrop(), sourceData.softMask,
|
||||
sourceData.alphaIsShape, sourceData.alphaFill, BlendMode::Normal, targetData.group.knockout, 0xFFFF, PDFFloatBitmap::OverprintMode::NoOveprint);
|
||||
sourceData.alphaIsShape, sourceData.alphaFill, BlendMode::Normal, targetData.group.knockout, 0xFFFF,
|
||||
PDFFloatBitmap::OverprintMode::NoOveprint, getPaintRect());
|
||||
|
||||
// Create draw buffer
|
||||
PDFFloatBitmapWithColorSpace* backdrop = getImmediateBackdrop();
|
||||
|
@ -1088,6 +1097,28 @@ PDFFloatBitmapWithColorSpace* PDFTransparencyRenderer::getBackdrop()
|
|||
}
|
||||
}
|
||||
|
||||
const PDFFloatBitmapWithColorSpace* PDFTransparencyRenderer::getInitialBackdrop() const
|
||||
{
|
||||
return &m_transparencyGroupDataStack.back().initialBackdrop;
|
||||
}
|
||||
|
||||
const PDFFloatBitmapWithColorSpace* PDFTransparencyRenderer::getImmediateBackdrop() const
|
||||
{
|
||||
return &m_transparencyGroupDataStack.back().immediateBackdrop;
|
||||
}
|
||||
|
||||
const PDFFloatBitmapWithColorSpace* PDFTransparencyRenderer::getBackdrop() const
|
||||
{
|
||||
if (isTransparencyGroupKnockout())
|
||||
{
|
||||
return getInitialBackdrop();
|
||||
}
|
||||
else
|
||||
{
|
||||
return getImmediateBackdrop();
|
||||
}
|
||||
}
|
||||
|
||||
const PDFColorSpacePointer& PDFTransparencyRenderer::getBlendColorSpace() const
|
||||
{
|
||||
return m_transparencyGroupDataStack.back().blendColorSpace;
|
||||
|
@ -1224,10 +1255,10 @@ PDFTransparencyRenderer::PDFMappedColor PDFTransparencyRenderer::getMappedFillCo
|
|||
|
||||
QRect PDFTransparencyRenderer::getPaintRect() const
|
||||
{
|
||||
return QRect(0, 0, getBackdrop()->getWidth(), getBackdrop()->getHeight());
|
||||
return QRect(0, 0, int(getBackdrop()->getWidth()), int(getBackdrop()->getHeight()));
|
||||
}
|
||||
|
||||
QRect PDFTransparencyRenderer::getActualFillRect(QRectF& fillRect) const
|
||||
QRect PDFTransparencyRenderer::getActualFillRect(const QRectF& fillRect) const
|
||||
{
|
||||
int xLeft = qFloor(fillRect.left()) - 1;
|
||||
int xRight = qCeil(fillRect.right()) + 1;
|
||||
|
@ -1242,6 +1273,22 @@ void PDFTransparencyRenderer::flushDrawBuffer()
|
|||
{
|
||||
if (m_drawBuffer.isModified())
|
||||
{
|
||||
PDFOverprintMode overprintMode = getGraphicState()->getOverprintMode();
|
||||
const bool useOverprint = (overprintMode.overprintFilling && m_drawBuffer.isContainsFilling()) ||
|
||||
(overprintMode.overprintStroking && m_drawBuffer.isContainsStroking());
|
||||
|
||||
PDFFloatBitmap::OverprintMode selectedOverprintMode = PDFFloatBitmap::OverprintMode::NoOveprint;
|
||||
if (useOverprint)
|
||||
{
|
||||
selectedOverprintMode = overprintMode.overprintMode == 0 ? PDFFloatBitmap::OverprintMode::Overprint_Mode_0
|
||||
: PDFFloatBitmap::OverprintMode::Overprint_Mode_1;
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
|
||||
m_drawBuffer.clear();
|
||||
}
|
||||
}
|
||||
|
@ -1547,12 +1594,16 @@ void PDFDrawBuffer::clear()
|
|||
}
|
||||
|
||||
m_activeColors = 0;
|
||||
m_containsFilling = false;
|
||||
m_containsStroking = false;
|
||||
m_modifiedRect = QRect();
|
||||
}
|
||||
|
||||
void PDFDrawBuffer::modify(QRect rect)
|
||||
void PDFDrawBuffer::modify(QRect rect, bool containsFilling, bool containsStroking)
|
||||
{
|
||||
m_modifiedRect = m_modifiedRect.united(rect);
|
||||
m_containsFilling |= containsFilling;
|
||||
m_containsStroking |= containsStroking;
|
||||
}
|
||||
|
||||
} // namespace pdf
|
||||
|
|
|
@ -200,6 +200,7 @@ public:
|
|||
/// \param mode Blend mode
|
||||
/// \param activeColorChannels Active color channels
|
||||
/// \param overprintMode Overprint mode
|
||||
/// \param blendRegion Blend region
|
||||
static void blend(const PDFFloatBitmap& source,
|
||||
PDFFloatBitmap& target,
|
||||
const PDFFloatBitmap& backdrop,
|
||||
|
@ -210,7 +211,8 @@ public:
|
|||
BlendMode mode,
|
||||
bool knockoutGroup,
|
||||
uint32_t activeColorChannels,
|
||||
OverprintMode overprintMode);
|
||||
OverprintMode overprintMode,
|
||||
QRect blendRegion);
|
||||
|
||||
private:
|
||||
void fillProcessColorChannels(PDFColorComponent value);
|
||||
|
@ -354,13 +356,24 @@ public:
|
|||
void clear();
|
||||
|
||||
/// Marks given area as modified
|
||||
void modify(QRect rect);
|
||||
void modify(QRect rect, bool containsFilling, bool containsStroking);
|
||||
|
||||
/// 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; }
|
||||
|
||||
bool isContainsFilling() const { return m_containsFilling; }
|
||||
bool isContainsStroking() const { return m_containsStroking; }
|
||||
|
||||
private:
|
||||
uint32_t m_activeColors = 0;
|
||||
bool m_containsFilling = false;
|
||||
bool m_containsStroking = false;
|
||||
QRect m_modifiedRect;
|
||||
};
|
||||
|
||||
|
@ -451,6 +464,7 @@ private:
|
|||
struct PDFTransparencyPainterState
|
||||
{
|
||||
QPainterPath clipPath; ///< Clipping path in device state coordinates
|
||||
PDFFloatBitmap softMask;
|
||||
};
|
||||
|
||||
struct PDFMappedColor
|
||||
|
@ -473,6 +487,9 @@ private:
|
|||
PDFFloatBitmapWithColorSpace* getInitialBackdrop();
|
||||
PDFFloatBitmapWithColorSpace* getImmediateBackdrop();
|
||||
PDFFloatBitmapWithColorSpace* getBackdrop();
|
||||
const PDFFloatBitmapWithColorSpace* getInitialBackdrop() const;
|
||||
const PDFFloatBitmapWithColorSpace* getImmediateBackdrop() const;
|
||||
const PDFFloatBitmapWithColorSpace* getBackdrop() const;
|
||||
const PDFColorSpacePointer& getBlendColorSpace() const;
|
||||
|
||||
PDFTransparencyPainterState* getPainterState() { return &m_painterStateStack.top(); }
|
||||
|
@ -492,7 +509,7 @@ private:
|
|||
|
||||
/// Returns fill area from fill rectangle
|
||||
/// \param fillRect Fill rectangle
|
||||
QRect getActualFillRect(QRectF& fillRect) const;
|
||||
QRect getActualFillRect(const QRectF& fillRect) const;
|
||||
|
||||
/// Flushes draw buffer
|
||||
void flushDrawBuffer();
|
||||
|
|
|
@ -47,6 +47,12 @@ OutputPreviewDialog::~OutputPreviewDialog()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
void OutputPreviewDialog::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
QDialog::resizeEvent(event);
|
||||
updateImage();
|
||||
}
|
||||
|
||||
void OutputPreviewDialog::updateImage()
|
||||
{
|
||||
const pdf::PDFPage* page = m_document->getCatalog()->getPage(ui->pageIndexScrollBar->value() - 1);
|
||||
|
|
|
@ -40,6 +40,8 @@ public:
|
|||
explicit OutputPreviewDialog(const pdf::PDFDocument* document, pdf::PDFWidget* widget, QWidget* parent);
|
||||
virtual ~OutputPreviewDialog() override;
|
||||
|
||||
virtual void resizeEvent(QResizeEvent* event) override;
|
||||
|
||||
private:
|
||||
void updateImage();
|
||||
|
||||
|
|
Loading…
Reference in New Issue