mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-04-17 11:47:34 +02:00
Bugfixing: correct handling of optional content
This commit is contained in:
parent
1fd01c14fd
commit
7ad4c46124
@ -516,7 +516,17 @@ PDFOptionalContentMembershipObject PDFOptionalContentMembershipObject::create(co
|
||||
{
|
||||
// First, scan all optional content groups
|
||||
PDFDocumentDataLoaderDecorator loader(document);
|
||||
std::vector<PDFObjectReference> ocgs = loader.readReferenceArrayFromDictionary(dictionary, "OCGs");
|
||||
std::vector<PDFObjectReference> ocgs;
|
||||
|
||||
PDFObject singleOCG = dictionary->get("OCGs");
|
||||
if (singleOCG.isReference())
|
||||
{
|
||||
ocgs = { singleOCG.getReference() };
|
||||
}
|
||||
else
|
||||
{
|
||||
ocgs = loader.readReferenceArrayFromDictionary(dictionary, "OCGs");
|
||||
}
|
||||
|
||||
if (!ocgs.empty())
|
||||
{
|
||||
|
@ -2741,29 +2741,29 @@ void PDFPageContentProcessor::operatorPaintXObject(PDFPageContentProcessor::PDFO
|
||||
|
||||
if (m_xobjectDictionary)
|
||||
{
|
||||
// According to the specification, XObjects are skipped entirely, as no operator was invoked.
|
||||
if (m_xobjectDictionary->hasKey("OC"))
|
||||
{
|
||||
const PDFObject& object = m_xobjectDictionary->get("OC");
|
||||
if (object.isReference())
|
||||
{
|
||||
if (isContentSuppressedByOC(object.getReference()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("Reference to optional content expected."));
|
||||
}
|
||||
}
|
||||
|
||||
const PDFObject& object = m_document->getObject(m_xobjectDictionary->get(name.name));
|
||||
if (object.isStream())
|
||||
{
|
||||
const PDFStream* stream = object.getStream();
|
||||
const PDFDictionary* streamDictionary = stream->getDictionary();
|
||||
|
||||
// According to the specification, XObjects are skipped entirely, as no operator was invoked.
|
||||
if (streamDictionary->hasKey("OC"))
|
||||
{
|
||||
const PDFObject& object = streamDictionary->get("OC");
|
||||
if (object.isReference())
|
||||
{
|
||||
if (isContentSuppressedByOC(object.getReference()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw PDFRendererException(RenderErrorType::Error, PDFTranslationContext::tr("Reference to optional content expected."));
|
||||
}
|
||||
}
|
||||
|
||||
PDFDocumentDataLoaderDecorator loader(m_document);
|
||||
QByteArray subtype = loader.readNameFromDictionary(streamDictionary, "Subtype");
|
||||
if (subtype == "Image")
|
||||
|
@ -413,6 +413,27 @@ void PDFPrecompiledPageGenerator::performImagePainting(const QImage& image)
|
||||
return;
|
||||
}
|
||||
|
||||
if (isTransparencyGroupActive())
|
||||
{
|
||||
PDFReal alpha = getEffectiveFillingAlpha();
|
||||
if (alpha != 1.0)
|
||||
{
|
||||
// Try to approximate transparency group using alpha channel
|
||||
QImage imageWithAlpha = image;
|
||||
QImage alphaChannel = imageWithAlpha.convertToFormat(QImage::Format_Alpha8);
|
||||
uchar* bits = alphaChannel.bits();
|
||||
|
||||
for (qsizetype i = 0, sizeInBytes = alphaChannel.sizeInBytes(); i < sizeInBytes; ++i)
|
||||
{
|
||||
bits[i] *= alpha;
|
||||
}
|
||||
|
||||
imageWithAlpha.setAlphaChannel(alphaChannel);
|
||||
m_precompiledPage->addImage(imageWithAlpha);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_precompiledPage->addImage(image);
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,9 @@ protected:
|
||||
/// Returns, if feature is turned on
|
||||
bool hasFeature(PDFRenderer::Feature feature) const { return m_features.testFlag(feature); }
|
||||
|
||||
/// Is transparency group active?
|
||||
bool isTransparencyGroupActive() const { return !m_transparencyGroupDataStack.empty(); }
|
||||
|
||||
private:
|
||||
/// Returns current pen (implementation)
|
||||
QPen getCurrentPenImpl() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user