Text knockout implementation

This commit is contained in:
Jakub Melka 2021-02-16 18:50:24 +01:00
parent 6844114397
commit 20f4e7f554
3 changed files with 20 additions and 7 deletions

View File

@ -2596,12 +2596,13 @@ void PDFPageContentProcessor::operatorTextBegin()
updateGraphicState();
++m_textBeginEndState;
performTextBegin(ProcessOrder::AfterOperation);
if (m_textBeginEndState > 1)
{
throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("Text object already started."));
}
performTextBegin(ProcessOrder::AfterOperation);
}
void PDFPageContentProcessor::operatorTextEnd()

View File

@ -697,6 +697,7 @@ void PDFTransparencyRenderer::beginPaint(QSize pixelSize)
const PDFFloatBitmap& PDFTransparencyRenderer::endPaint()
{
Q_ASSERT(m_active);
m_textTransparencyGroupGuard.reset(); // Just safeguard - ET operator may not be present
m_pageTransparencyGroupGuard.reset();
m_active = false;
m_painterStateStack.pop();
@ -882,6 +883,7 @@ void PDFTransparencyRenderer::collapseSpotColorsToDeviceColors(PDFFloatBitmapWit
void PDFTransparencyRenderer::performPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule)
{
Q_UNUSED(text);
Q_UNUSED(fillRule);
QMatrix worldMatrix = getCurrentWorldMatrix();
@ -1031,10 +1033,7 @@ void PDFTransparencyRenderer::performPathPainting(const QPainterPath& path, bool
}
}
if (!text || !getGraphicState()->getTextKnockout())
{
flushDrawBuffer();
}
flushDrawBuffer();
}
void PDFTransparencyRenderer::performClipping(const QPainterPath& path, Qt::FillRule fillRule)
@ -1229,11 +1228,22 @@ void PDFTransparencyRenderer::performEndTransparencyGroup(ProcessOrder order, co
}
}
void PDFTransparencyRenderer::performTextBegin(ProcessOrder order)
{
if (order == ProcessOrder::AfterOperation && getGraphicState()->getTextKnockout())
{
// In a case of text knockout, use text transparency group of type knockout
PDFTransparencyGroup transparencyGroup;
transparencyGroup.knockout = true;
m_textTransparencyGroupGuard.reset(new PDFTransparencyGroupGuard(this, qMove(transparencyGroup)));
}
}
void PDFTransparencyRenderer::performTextEnd(ProcessOrder order)
{
if (order == ProcessOrder::AfterOperation)
if (order == ProcessOrder::BeforeOperation)
{
flushDrawBuffer();
m_textTransparencyGroupGuard.reset();
}
}

View File

@ -562,6 +562,7 @@ public:
virtual void performRestoreGraphicState(ProcessOrder order) override;
virtual void performBeginTransparencyGroup(ProcessOrder order, const PDFTransparencyGroup& transparencyGroup) override;
virtual void performEndTransparencyGroup(ProcessOrder order, const PDFTransparencyGroup& transparencyGroup) override;
virtual void performTextBegin(ProcessOrder order) override;
virtual void performTextEnd(ProcessOrder order) override;
virtual void performImagePainting(const QImage& image) override;
virtual void performMeshPainting(const PDFMesh& mesh);
@ -689,6 +690,7 @@ private:
PDFColorSpacePointer m_deviceColorSpace; ///< Device color space (color space for final result)
PDFColorSpacePointer m_processColorSpace; ///< Process color space (color space, in which is page graphic's blended)
std::unique_ptr<PDFTransparencyGroupGuard> m_pageTransparencyGroupGuard;
std::unique_ptr<PDFTransparencyGroupGuard> m_textTransparencyGroupGuard;
std::vector<PDFTransparencyGroupPainterData> m_transparencyGroupDataStack;
std::stack<PDFTransparencyPainterState> m_painterStateStack;
const PDFInkMapper* m_inkMapper;